63 #define PLY_BINARY_BE 2     64 #define PLY_BINARY_LE 3    100     int external_type = 0; 
   101     int internal_type = 0; 
   105     int count_external = 0; 
   106     int count_internal = 0; 
   107     int count_offset = 0; 
   119     int other_offset = 0; 
   136     string(
"invalid"), string(
"char"),  string(
"short"),
   137     string(
"int"),   string(
"uchar"), string(
"ushort"),
   138     string(
"uint"), string(
"float"), string(
"double"),
   152 vector<string> 
get_words(FILE*, 
string&);
   168 void store_item(
char*, 
int, 
int, 
unsigned int, 
double);
   177 void get_ascii_item(
const char*, 
int, 
int*, 
unsigned int*, 
double*);
   179     FILE*, 
int, 
int, 
int*, 
unsigned int*, 
double*);  
   206     if (fp == 
nullptr) 
return (
nullptr);
   209     auto* plyfile = 
new PlyFile(fp);
   211     plyfile->file_type = file_type;
   212     plyfile->version = 1.0;
   217     plyfile->elems.resize(elem_names.size());
   218     for (
size_t i = 0; i < elem_names.size(); i++)
   220         plyfile->elems[i].name = elem_names[i];
   242     const char* name, 
const vector<string>& elem_names, 
int file_type,
   250     fp = 
fopen(name, 
"w");
   258     plyfile = 
ply_write(fp, elem_names, file_type);
   259     if (plyfile == 
nullptr) 
return (
nullptr);
   281     PlyFile* plyfile, 
const string& elem_name, 
int nelems,
   282     vector<PlyProperty>& prop_list)
   287         throw std::runtime_error(
format(
   288             "ply_describe_element: can't find element '%s'",
   295     const size_t nprops = prop_list.size();
   296     elem->
props.resize(nprops);
   299     for (
size_t i = 0; i < nprops; i++)
   301         elem->
props[i] = prop_list[i];
   323             stderr, 
"ply_describe_property: can't find element '%s'\n",
   329     elem->
props.push_back(*prop);
   351         throw std::runtime_error(
format(
   352             "ply_element_count: can't find element '%s'", elem_name.c_str()));
   367     FILE* fp = plyfile->
fp;
   374             fprintf(fp, 
"format ascii 1.0\n");
   377             fprintf(fp, 
"format binary_big_endian 1.0\n");
   380             fprintf(fp, 
"format binary_little_endian 1.0\n");
   383             throw std::runtime_error(
format(
   384                 "ply_header_complete: bad file type = %d", plyfile->
file_type));
   389     for (
auto& comment : plyfile->
comments)
   390         fprintf(fp, 
"comment %s\n", comment.c_str());
   394     for (
auto& i : plyfile->
obj_info) 
fprintf(fp, 
"obj_info %s\n", i.c_str());
   398     for (
auto& i : plyfile->
elems)
   404         for (
const auto& j : elem->
props)
   442         throw std::runtime_error(
format(
   443             "ply_elements_setup: can't find element '%s'", elem_name.c_str()));
   460     FILE* fp = plyfile->
fp;
   461     char *elem_data, *item;
   465     unsigned int uint_val;
   470     elem_data = (
char*)elem_ptr;
   471     other_ptr = (
char**)(((
char*)elem_ptr) + elem->
other_offset);
   480         for (
size_t j = 0; j < elem->
props.size(); j++)
   484                 elem_data = *other_ptr;
   486                 elem_data = (
char*)elem_ptr;
   495                 const size_t list_count = uint_val;
   496                 item_ptr = (
char**)(elem_data + prop->
offset);
   499                 for (
size_t k = 0; k < list_count; k++)
   511                 item = elem_data + prop->
offset;
   527         for (
size_t j = 0; j < elem->
props.size(); j++)
   531                 elem_data = *other_ptr;
   533                 elem_data = (
char*)elem_ptr;
   543                 const size_t list_count = uint_val;
   544                 item_ptr = (
char**)(elem_data + prop->
offset);
   547                 for (
size_t k = 0; k < list_count; k++)
   559                 item = elem_data + prop->
offset;
   581     plyfile->
comments.push_back(comment);
   595     plyfile->
obj_info.push_back(obj_info);
   620     if (fp == 
nullptr) 
return (
nullptr);
   623     auto* plyfile = 
new PlyFile(fp);
   627     vector<string> words = 
get_words(plyfile->fp, orig_line);
   629     if (words.empty() || words[0] != 
"ply") 
return nullptr;
   631     while (!words.empty())
   635         if (words[0] == 
"format")
   637             if (words.size() != 3) 
return (
nullptr);
   638             if (words[1] == 
"ascii")
   640             else if (words[1] == 
"binary_big_endian")
   642             else if (words[1] == 
"binary_little_endian")
   646             plyfile->version = 
d2f(atof(words[2].c_str()));
   649         else if (words[0] == 
"element")
   651         else if (words[0] == 
"property")
   653         else if (words[0] == 
"comment")
   655         else if (words[0] == 
"obj_info")
   657         else if (words[0] == 
"end_header")
   660         words = 
get_words(plyfile->fp, orig_line);
   666     for (
auto& i : plyfile->elems)
   676     for (
auto& elem : plyfile->elems) elem_names.push_back(elem.name);
   698     const char* filename, vector<string>& elem_names, 
int* file_type,
   706     fp = 
fopen(filename, 
"r");
   707     if (fp == 
nullptr) 
return (
nullptr);
   739     PlyFile* plyfile, 
const string& elem_name, 
int& nelems, 
int& nprops)
   743     if (elem == 
nullptr) 
return vector<PlyProperty>();
   746     nprops = elem->
props.size();
   778     if (prop_ptr == 
nullptr)
   781             stderr, 
"Warning:  Can't find property '%s' in element '%s'\n",
   782             prop->
name.c_str(), elem_name.c_str());
   877     if (ply == 
nullptr) 
return;
   896     for (
auto& elem : plyfile->
elems)
   897         if (element == elem.name) 
return &elem;
   915     PlyElement* elem, 
const std::string& prop_name, 
int* index)
   917     for (
size_t i = 0; i < elem->
props.size(); i++)
   918         if (
string(prop_name) == elem->
props[i].name)
   921             return &elem->
props[i];
   939     char *elem_data, *item = 
nullptr;
   943     unsigned int uint_val;
   948     char* other_data = 
nullptr;
   971     vector<string> words = 
get_words(plyfile->
fp, orig_line);
   974         throw std::runtime_error(
"ply_get_element: unexpected end of file");
   978     for (
size_t j = 0; j < elem->
props.size(); j++)
   981         store_it = (elem->
store_prop[j] | other_flag);
   985             elem_data = elem_ptr;
   987             elem_data = other_data;
   995                 &uint_val, &double_val);
  1005             list_count = int_val;
  1007             store_array = (
char**)(elem_data + prop->
offset);
  1009             if (list_count == 0)
  1011                 if (store_it) *store_array = 
nullptr;
  1018                         (
char*)malloc(
sizeof(
char) * item_size * list_count);
  1020                     *store_array = item_ptr;
  1024                 for (
int k = 0; k < list_count; k++)
  1028                         &int_val, &uint_val, &double_val);
  1043                 &uint_val, &double_val);
  1046                 item = elem_data + prop->
offset;
  1064     FILE* fp = plyfile->
fp;
  1065     char *elem_data, *item = 
nullptr;
  1069     unsigned int uint_val;
  1074     char* other_data = 
nullptr;
  1089         other_data = (
char*)malloc(elem->
other_size);
  1099     for (
size_t j = 0; j < elem->
props.size(); j++)
  1102         store_it = (elem->
store_prop[j] | other_flag);
  1106             elem_data = elem_ptr;
  1108             elem_data = other_data;
  1116                     &uint_val, &double_val))
  1121                     "RPly::binary_get_element: Error reading binary file!\n");
  1133             list_count = int_val;
  1142             store_array = (
char**)(elem_data + prop->
offset);
  1143             if (list_count == 0)
  1145                 if (store_it) *store_array = 
nullptr;
  1152                         (
char*)malloc(
sizeof(
char) * item_size * list_count);
  1154                     *store_array = item_ptr;
  1158                 for (
int k = 0; k < list_count; k++)
  1162                             &uint_val, &double_val))
  1167                             "RPly::binary_get_element: Error reading binary "  1184                     fp, bin_file_type, prop->
external_type, &int_val, &uint_val,
  1190                     "RPly::binary_get_element: Error reading binary file!\n");
  1195                 item = elem_data + prop->
offset;
  1216         throw std::runtime_error(
  1217             format(
"write_scalar_type: bad data code = %d", code));
  1241 #define BIG_STRING 4096  1244     vector<string> words;
  1250     if (result == 
nullptr)
  1252         orig_line = string();
  1256     orig_line = string(str);
  1275     unsigned char* puchar;
  1278     unsigned short int* pushort;
  1280     unsigned int* puint;
  1284     unsigned int uint_value;
  1285     double double_value;
  1290             pchar = (
char*)item;
  1292             return ((
double)int_value);
  1294             puchar = (
unsigned char*)item;
  1295             int_value = *puchar;
  1296             return ((
double)int_value);
  1298             pshort = (
short int*)item;
  1299             int_value = *pshort;
  1300             return ((
double)int_value);
  1302             pushort = (
unsigned short int*)item;
  1303             int_value = *pushort;
  1304             return ((
double)int_value);
  1308             return ((
double)int_value);
  1310             puint = (
unsigned int*)item;
  1311             uint_value = *puint;
  1312             return ((
double)uint_value);
  1314             pfloat = (
float*)item;
  1315             double_value = *pfloat;
  1316             return (double_value);
  1318             pdouble = (
double*)item;
  1319             double_value = *pdouble;
  1320             return (double_value);
  1322             throw std::runtime_error(
  1323                 format(
"get_item_value: bad type = %d", type));
  1339     FILE* fp, 
int int_val, 
unsigned int uint_val, 
double double_val, 
int type)
  1341     unsigned char uchar_val;
  1343     unsigned short ushort_val;
  1351             fwrite(&char_val, 1, 1, fp);
  1354             short_val = int_val;
  1355             fwrite(&short_val, 2, 1, fp);
  1358             fwrite(&int_val, 4, 1, fp);
  1361             uchar_val = uint_val;
  1362             fwrite(&uchar_val, 1, 1, fp);
  1365             ushort_val = uint_val;
  1366             fwrite(&ushort_val, 2, 1, fp);
  1369             fwrite(&uint_val, 4, 1, fp);
  1372             float_val = 
d2f(double_val);
  1373             fwrite(&float_val, 4, 1, fp);
  1376             fwrite(&double_val, 8, 1, fp);
  1379             throw std::runtime_error(
  1380                 format(
"write_binary_item: bad type = %d", type));
  1396     FILE* fp, 
int int_val, 
unsigned int uint_val, 
double double_val, 
int type)
  1412             fprintf(fp, 
"%g ", double_val);
  1415             throw std::runtime_error(
  1416                 format(
"write_ascii_item: bad type = %d", type));
  1435     void* ptr, 
int type, 
int* int_val, 
unsigned int* uint_val,
  1441             *int_val = *((
char*)ptr);
  1442             *uint_val = *int_val;
  1443             *double_val = *int_val;
  1446             *uint_val = *((
unsigned char*)ptr);
  1447             *int_val = *uint_val;
  1448             *double_val = *uint_val;
  1451             *int_val = *((
short int*)ptr);
  1452             *uint_val = *int_val;
  1453             *double_val = *int_val;
  1456             *uint_val = *((
unsigned short int*)ptr);
  1457             *int_val = *uint_val;
  1458             *double_val = *uint_val;
  1461             *int_val = *((
int*)ptr);
  1462             *uint_val = *int_val;
  1463             *double_val = *int_val;
  1466             *uint_val = *((
unsigned int*)ptr);
  1467             *int_val = *uint_val;
  1468             *double_val = *uint_val;
  1471             *double_val = *((
float*)ptr);
  1472             *int_val = 
static_cast<int>(*double_val);
  1473             *uint_val = 
static_cast<unsigned int>(*double_val);
  1476             *double_val = *((
double*)ptr);
  1477             *int_val = 
static_cast<int>(*double_val);
  1478             *uint_val = 
static_cast<unsigned int>(*double_val);
  1481             throw std::runtime_error(
  1482                 format(
"get_stored_item: bad type = %d", type));
  1503     FILE* fp, 
int bin_file_type, 
int type, 
int* int_val, 
unsigned int* uint_val,
  1514             if (fread(ptr, 1, 1, fp) != 1) 
return 0;
  1515             *int_val = *((
char*)ptr);
  1516             *uint_val = *int_val;
  1517             *double_val = *int_val;
  1520             if (fread(ptr, 1, 1, fp) != 1) 
return 0;
  1521             *uint_val = *((
unsigned char*)ptr);
  1522             *int_val = *uint_val;
  1523             *double_val = *uint_val;
  1526             if (fread(ptr, 2, 1, fp) != 1) 
return 0;
  1527             *int_val = *((
short int*)ptr);
  1528             *uint_val = *int_val;
  1529             *double_val = *int_val;
  1532             if (fread(ptr, 2, 1, fp) != 1) 
return 0;
  1533             *uint_val = *((
unsigned short int*)ptr);
  1534             *int_val = *uint_val;
  1535             *double_val = *uint_val;
  1538             if (fread(ptr, 4, 1, fp) != 1) 
return 0;
  1539             *int_val = *((
int*)ptr);
  1540             *uint_val = *int_val;
  1541             *double_val = *int_val;
  1544             if (fread(ptr, 4, 1, fp) != 1) 
return 0;
  1545             *uint_val = *((
unsigned int*)ptr);
  1546             *int_val = *uint_val;
  1547             *double_val = *uint_val;
  1550             if (fread(ptr, 4, 1, fp) != 1) 
return 0;
  1551             *double_val = *((
float*)ptr);
  1552             *int_val = 
static_cast<int>(*double_val);
  1553             *uint_val = 
static_cast<unsigned int>(*double_val);
  1556             if (fread(ptr, 8, 1, fp) != 1) 
return 0;
  1557             *double_val = *((
double*)ptr);
  1558             *int_val = 
static_cast<int>(*double_val);
  1559             *uint_val = 
static_cast<unsigned int>(*double_val);
  1562             throw std::runtime_error(
  1563                 format(
"get_binary_item: bad type = %d", type));
  1569 #if MRPT_IS_BIG_ENDIAN  1577         int int_val2 = *int_val;
  1578         unsigned int uint_val2 = *uint_val;
  1579         double double_val2 = *double_val;
  1603     const char* word, 
int type, 
int* int_val, 
unsigned int* uint_val,
  1613             *int_val = atoi(word);
  1614             *uint_val = *int_val;
  1615             *double_val = *int_val;
  1619             *uint_val = strtoul(word, (
char**)
nullptr, 10);
  1620             *int_val = *uint_val;
  1621             *double_val = *uint_val;
  1626             *double_val = atof(word);
  1627             *int_val = (int)*double_val;
  1628             *uint_val = (
unsigned int)*double_val;
  1632             throw std::runtime_error(
  1633                 format(
"get_ascii_item: bad type = %d", type));
  1652     char* item, 
int type, 
int int_val, 
unsigned int uint_val, 
double double_val)
  1654     unsigned char* puchar;
  1656     unsigned short int* pushort;
  1658     unsigned int* puint;
  1668             puchar = (
unsigned char*)item;
  1672             pshort = (
short*)item;
  1676             pushort = (
unsigned short*)item;
  1677             *pushort = uint_val;
  1684             puint = (
unsigned int*)item;
  1688             pfloat = (
float*)item;
  1689             *pfloat = 
d2f(double_val);
  1692             pdouble = (
double*)item;
  1693             *pdouble = double_val;
  1696             throw std::runtime_error(
format(
"store_item: bad type = %d", type));
  1712     plyfile->
elems.emplace_back();
  1715     elem->
name = words[1];
  1716     elem->
num = atoi(words[2].c_str());
  1754     elem->
props.emplace_back();
  1760     if (words[1] == 
"list")
  1764         prop->
name = words[4];
  1770         prop->
name = words[2];
  1812     float x{0}, y{0}, z{0};
  1813     float r{0}, g{0}, b{0};
  1844 bool PLY_Importer::loadFromPlyFile(
  1845     const std::string& filename, std::vector<std::string>* file_comments,
  1846     std::vector<std::string>* file_obj_info)
  1851         vector<string> elist;  
  1860         for (
const auto& elem_name : elist)
  1863             int num_elems = 0, nprops = 0;
  1872             if (
"vertex" == elem_name)
  1879                 this->PLY_import_set_vertex_count(num_elems);
  1880                 for (
int j = 0; j < num_elems; j++)
  1893                         this->PLY_import_set_vertex(j, xyz, &col);
  1900                         this->PLY_import_set_vertex(j, xyz, &col);
  1904                         this->PLY_import_set_vertex(j, xyz);
  1917             vector<string> strs;
  1919             *file_comments = std::vector<std::string>(strs);
  1925             vector<string> strs;
  1927             *file_obj_info = std::vector<std::string>(strs);
  1934         m_ply_import_last_error = std::string();
  1937     catch (
const std::exception& e)
  1940         m_ply_import_last_error = std::string(e.what());
  1945 bool PLY_Exporter::saveToPlyFile(
  1946     const std::string& filename, 
bool save_in_binary,
  1947     const std::vector<std::string>& file_comments,
  1948     const std::vector<std::string>& file_obj_info)
 const  1953         vector<string> elem_names;
  1954         elem_names.emplace_back(
"vertex");
  1955         elem_names.emplace_back(
"face");
  1967             filename.c_str(), elem_names,
  1969 #if MRPT_IS_BIG_ENDIAN  1979         const size_t nverts = this->PLY_export_get_vertex_count();
  1980         const size_t nfaces = this->PLY_export_get_face_count();
  1988             this->PLY_export_get_vertex(0, pt, pt_has_color, pt_color);
  2005         for (
const auto& file_comment : file_comments)
  2016         for (
size_t i = 0; i < nverts; i++)
  2021             this->PLY_export_get_vertex(i, pt, pt_has_color, pt_color);
  2030                     (1.0f / 3.0f) * (pt_color.
R + pt_color.
G + pt_color.
B);
  2050         m_ply_export_last_error = std::string();
  2053     catch (
const std::exception& e)
  2056         m_ply_export_last_error = std::string(e.what());
 
const char DONT_STORE_PROP
 
void ply_put_obj_info(PlyFile *plyfile, const string &obj_info)
 
void get_ascii_item(const char *, int, int *, unsigned int *, double *)
 
vector< string > comments
 
vector< PlyProperty > props
 
PlyElement * find_element(PlyFile *, const std::string &s)
 
std::string std::string format(std::string_view fmt, ARGS &&... args)
 
size_t size(const MATRIXLIKE &m, const int dim)
 
int void fclose(FILE *f)
An OS-independent version of fclose. 
 
const PlyProperty vert_props[]
 
void reverseBytes(const T &v_in, T &v_out)
Reverse the order of the bytes of a given type (useful for transforming btw little/big endian) ...
 
vector< char > store_prop
 
void ply_get_obj_info(PlyFile *plyfile, vector< string > &obj_info)
 
struct PlyProperty PlyProperty
 
PlyFile * ply_open_for_writing(const char *name, const vector< string > &elem_names, int file_type, float *version)
 
int get_binary_item(FILE *, int, int, int *, unsigned int *, double *)
 
void add_property(PlyFile *, const vector< string > &)
 
void tokenize(const std::string &inString, const std::string &inDelimiters, OUT_CONTAINER &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters. 
 
#define ASSERT_(f)
Defines an assertion mechanism. 
 
float d2f(const double d)
shortcut for static_cast<float>(double) 
 
const int ply_type_size[]
 
This base provides a set of functions for maths stuff. 
 
double get_item_value(const char *, int)
 
PlyFile(FILE *_fp=nullptr)
 
void ply_put_element_setup(PlyFile *plyfile, const string &elem_name)
 
void add_comment(PlyFile *, const string &)
 
void ply_describe_element(PlyFile *plyfile, const string &elem_name, int nelems, vector< PlyProperty > &prop_list)
 
const PlyProperty face_props[]
 
void ply_describe_property(PlyFile *plyfile, const char *elem_name, const PlyProperty *prop)
 
PlyFile * ply_read(FILE *fp, vector< string > &elem_names)
 
void add_element(PlyFile *, const vector< string > &)
 
int get_prop_type(const string &type_name)
 
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf. 
 
const std::string type_names[]
 
vector< PlyProperty > ply_get_element_description(PlyFile *plyfile, const string &elem_name, int &nelems, int &nprops)
 
void add_obj_info(PlyFile *, const string &)
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
void write_binary_item(FILE *, int, unsigned int, double, int)
 
void ply_close(PlyFile *plyfile)
 
void ply_put_comment(PlyFile *plyfile, const string &comment)
 
void ply_get_element(PlyFile *plyfile, void *elem_ptr)
 
void write_scalar_type(FILE *, int)
 
void write_ascii_item(FILE *, int, unsigned int, double, int)
 
PlyFile * ply_write(FILE *fp, const vector< string > &elem_names, int file_type)
 
PlyProperty * find_property(PlyElement *, const std::string &s, int *)
 
void get_stored_item(void *, int, int *, unsigned int *, double *)
 
An RGBA color - floats in the range [0,1]. 
 
The namespace for 3D scene representation and rendering. 
 
void ascii_get_element(PlyFile *, char *)
 
void copy_property(PlyProperty *, const PlyProperty *)
 
vector< string > get_words(FILE *, string &)
 
void binary_get_element(PlyFile *, char *)
 
std::string trim(const std::string &str)
Removes leading and trailing spaces. 
 
vector< PlyElement > elems
 
struct PlyElement PlyElement
 
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen. 
 
void ply_get_property(PlyFile *plyfile, const string &elem_name, const PlyProperty *prop)
 
void store_item(char *, int, int, unsigned int, double)
 
void ply_header_complete(PlyFile *plyfile)
 
void ply_get_info(PlyFile *ply, float *version, int *file_type)
 
vector< string > obj_info
 
void ply_element_count(PlyFile *plyfile, const string &elem_name, int nelems)
 
void ply_get_comments(PlyFile *plyfile, vector< string > &comments)
 
PlyFile * ply_open_for_reading(const char *filename, vector< string > &elem_names, int *file_type, float *version)
 
void ply_put_element(PlyFile *plyfile, void *elem_ptr)