63 #define PLY_BINARY_BE 2 64 #define PLY_BINARY_LE 3 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,
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 = 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;
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(
975 format(
"ply_get_element: unexpected end of file"));
979 for (
size_t j = 0; j < elem->
props.size(); j++)
982 store_it = (elem->
store_prop[j] | other_flag);
986 elem_data = elem_ptr;
988 elem_data = other_data;
996 &uint_val, &double_val);
1006 list_count = int_val;
1008 store_array = (
char**)(elem_data + prop->
offset);
1010 if (list_count == 0)
1012 if (store_it) *store_array =
nullptr;
1019 (
char*)malloc(
sizeof(
char) * item_size * list_count);
1021 *store_array = item_ptr;
1025 for (
int k = 0; k < list_count; k++)
1029 &int_val, &uint_val, &double_val);
1044 &uint_val, &double_val);
1047 item = elem_data + prop->
offset;
1065 FILE* fp = plyfile->
fp;
1066 char *elem_data, *item =
nullptr;
1070 unsigned int uint_val;
1075 char* other_data =
nullptr;
1090 other_data = (
char*)malloc(elem->
other_size);
1100 for (
size_t j = 0; j < elem->
props.size(); j++)
1103 store_it = (elem->
store_prop[j] | other_flag);
1107 elem_data = elem_ptr;
1109 elem_data = other_data;
1117 &uint_val, &double_val))
1122 "RPly::binary_get_element: Error reading binary file!\n");
1134 list_count = int_val;
1143 store_array = (
char**)(elem_data + prop->
offset);
1144 if (list_count == 0)
1146 if (store_it) *store_array =
nullptr;
1153 (
char*)malloc(
sizeof(
char) * item_size * list_count);
1155 *store_array = item_ptr;
1159 for (
int k = 0; k < list_count; k++)
1163 &uint_val, &double_val))
1168 "RPly::binary_get_element: Error reading binary " 1185 fp, bin_file_type, prop->
external_type, &int_val, &uint_val,
1191 "RPly::binary_get_element: Error reading binary file!\n");
1196 item = elem_data + prop->
offset;
1217 throw std::runtime_error(
1218 format(
"write_scalar_type: bad data code = %d",
code));
1242 #define BIG_STRING 4096 1245 vector<string> words;
1251 if (result ==
nullptr)
1276 unsigned char* puchar;
1279 unsigned short int* pushort;
1281 unsigned int* puint;
1285 unsigned int uint_value;
1286 double double_value;
1291 pchar = (
char*)item;
1293 return ((
double)int_value);
1295 puchar = (
unsigned char*)item;
1296 int_value = *puchar;
1297 return ((
double)int_value);
1299 pshort = (
short int*)item;
1300 int_value = *pshort;
1301 return ((
double)int_value);
1303 pushort = (
unsigned short int*)item;
1304 int_value = *pushort;
1305 return ((
double)int_value);
1309 return ((
double)int_value);
1311 puint = (
unsigned int*)item;
1312 uint_value = *puint;
1313 return ((
double)uint_value);
1315 pfloat = (
float*)item;
1316 double_value = *pfloat;
1317 return (double_value);
1319 pdouble = (
double*)item;
1320 double_value = *pdouble;
1321 return (double_value);
1323 throw std::runtime_error(
1324 format(
"get_item_value: bad type = %d",
type));
1340 FILE* fp,
int int_val,
unsigned int uint_val,
double double_val,
int type)
1342 unsigned char uchar_val;
1344 unsigned short ushort_val;
1352 fwrite(&char_val, 1, 1, fp);
1355 short_val = int_val;
1356 fwrite(&short_val, 2, 1, fp);
1359 fwrite(&int_val, 4, 1, fp);
1362 uchar_val = uint_val;
1363 fwrite(&uchar_val, 1, 1, fp);
1366 ushort_val = uint_val;
1367 fwrite(&ushort_val, 2, 1, fp);
1370 fwrite(&uint_val, 4, 1, fp);
1373 float_val = double_val;
1374 fwrite(&float_val, 4, 1, fp);
1377 fwrite(&double_val, 8, 1, fp);
1380 throw std::runtime_error(
1381 format(
"write_binary_item: bad type = %d",
type));
1397 FILE* fp,
int int_val,
unsigned int uint_val,
double double_val,
int type)
1413 fprintf(fp,
"%g ", double_val);
1416 throw std::runtime_error(
1417 format(
"write_ascii_item: bad type = %d",
type));
1436 void* ptr,
int type,
int* int_val,
unsigned int* uint_val,
1442 *int_val = *((
char*)ptr);
1443 *uint_val = *int_val;
1444 *double_val = *int_val;
1447 *uint_val = *((
unsigned char*)ptr);
1448 *int_val = *uint_val;
1449 *double_val = *uint_val;
1452 *int_val = *((
short int*)ptr);
1453 *uint_val = *int_val;
1454 *double_val = *int_val;
1457 *uint_val = *((
unsigned short int*)ptr);
1458 *int_val = *uint_val;
1459 *double_val = *uint_val;
1462 *int_val = *((
int*)ptr);
1463 *uint_val = *int_val;
1464 *double_val = *int_val;
1467 *uint_val = *((
unsigned int*)ptr);
1468 *int_val = *uint_val;
1469 *double_val = *uint_val;
1472 *double_val = *((
float*)ptr);
1473 *int_val = *double_val;
1474 *uint_val = *double_val;
1477 *double_val = *((
double*)ptr);
1478 *int_val = *double_val;
1479 *uint_val = *double_val;
1482 throw std::runtime_error(
1483 format(
"get_stored_item: bad type = %d",
type));
1504 FILE* fp,
int bin_file_type,
int type,
int* int_val,
unsigned int* uint_val,
1515 if (fread(ptr, 1, 1, fp) != 1)
return 0;
1516 *int_val = *((
char*)ptr);
1517 *uint_val = *int_val;
1518 *double_val = *int_val;
1521 if (fread(ptr, 1, 1, fp) != 1)
return 0;
1522 *uint_val = *((
unsigned char*)ptr);
1523 *int_val = *uint_val;
1524 *double_val = *uint_val;
1527 if (fread(ptr, 2, 1, fp) != 1)
return 0;
1528 *int_val = *((
short int*)ptr);
1529 *uint_val = *int_val;
1530 *double_val = *int_val;
1533 if (fread(ptr, 2, 1, fp) != 1)
return 0;
1534 *uint_val = *((
unsigned short int*)ptr);
1535 *int_val = *uint_val;
1536 *double_val = *uint_val;
1539 if (fread(ptr, 4, 1, fp) != 1)
return 0;
1540 *int_val = *((
int*)ptr);
1541 *uint_val = *int_val;
1542 *double_val = *int_val;
1545 if (fread(ptr, 4, 1, fp) != 1)
return 0;
1546 *uint_val = *((
unsigned int*)ptr);
1547 *int_val = *uint_val;
1548 *double_val = *uint_val;
1551 if (fread(ptr, 4, 1, fp) != 1)
return 0;
1552 *double_val = *((
float*)ptr);
1553 *int_val = *double_val;
1554 *uint_val = *double_val;
1557 if (fread(ptr, 8, 1, fp) != 1)
return 0;
1558 *double_val = *((
double*)ptr);
1559 *int_val = *double_val;
1560 *uint_val = *double_val;
1563 throw std::runtime_error(
1564 format(
"get_binary_item: bad type = %d",
type));
1570 #if MRPT_IS_BIG_ENDIAN 1578 int int_val2 = *int_val;
1579 unsigned int uint_val2 = *uint_val;
1580 double double_val2 = *double_val;
1604 const char* word,
int type,
int* int_val,
unsigned int* uint_val,
1614 *int_val = atoi(word);
1615 *uint_val = *int_val;
1616 *double_val = *int_val;
1620 *uint_val = strtoul(word, (
char**)
nullptr, 10);
1621 *int_val = *uint_val;
1622 *double_val = *uint_val;
1627 *double_val = atof(word);
1628 *int_val = (int)*double_val;
1629 *uint_val = (
unsigned int)*double_val;
1633 throw std::runtime_error(
1634 format(
"get_ascii_item: bad type = %d",
type));
1653 char* item,
int type,
int int_val,
unsigned int uint_val,
double double_val)
1655 unsigned char* puchar;
1657 unsigned short int* pushort;
1659 unsigned int* puint;
1669 puchar = (
unsigned char*)item;
1673 pshort = (
short*)item;
1677 pushort = (
unsigned short*)item;
1678 *pushort = uint_val;
1685 puint = (
unsigned int*)item;
1689 pfloat = (
float*)item;
1690 *pfloat = double_val;
1693 pdouble = (
double*)item;
1694 *pdouble = double_val;
1697 throw std::runtime_error(
format(
"store_item: bad type = %d",
type));
1713 plyfile->
elems.emplace_back();
1716 elem->
name = words[1];
1717 elem->
num = atoi(words[2].c_str());
1755 elem->
props.emplace_back();
1761 if (words[1] ==
"list")
1765 prop->
name = words[4];
1771 prop->
name = words[2];
1845 bool PLY_Importer::loadFromPlyFile(
1846 const std::string& filename, std::vector<std::string>* file_comments,
1847 std::vector<std::string>* file_obj_info)
1852 vector<string> elist;
1861 for (
const auto& elem_name : elist)
1864 int num_elems = 0, nprops = 0;
1873 if (
"vertex" == elem_name)
1880 this->PLY_import_set_vertex_count(num_elems);
1881 for (
int j = 0; j < num_elems; j++)
1894 this->PLY_import_set_vertex(j, xyz, &col);
1901 this->PLY_import_set_vertex(j, xyz, &col);
1905 this->PLY_import_set_vertex(j, xyz);
1918 vector<string> strs;
1920 *file_comments = std::vector<std::string>(strs);
1926 vector<string> strs;
1928 *file_obj_info = std::vector<std::string>(strs);
1938 catch (
const std::exception& e)
1946 bool PLY_Exporter::saveToPlyFile(
1948 const std::vector<std::string>& file_comments,
1949 const std::vector<std::string>& file_obj_info)
const 1954 vector<string> elem_names;
1955 elem_names.emplace_back(
"vertex");
1956 elem_names.emplace_back(
"face");
1968 filename.c_str(), elem_names,
1970 #if MRPT_IS_BIG_ENDIAN 1980 const size_t nverts = this->PLY_export_get_vertex_count();
1981 const size_t nfaces = this->PLY_export_get_face_count();
1989 this->PLY_export_get_vertex(0, pt, pt_has_color, pt_color);
2006 for (
const auto& file_comment : file_comments)
2017 for (
size_t i = 0; i < nverts; i++)
2022 this->PLY_export_get_vertex(i, pt, pt_has_color, pt_color);
2031 (1.0f / 3.0f) * (pt_color.
R + pt_color.
G + pt_color.
B);
2054 catch (
const std::exception& e)
#define offsetof(_structure, _field)
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)
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.
const int ply_type_size[]
This base provides a set of functions for maths stuff.
Lightweight 3D point (float version).
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[]
GLsizei const GLchar ** string
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 *)
A RGB color - floats in the range [0,1].
The namespace for 3D scene representation and rendering.
GLuint const GLchar * name
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)
GLenum GLsizei GLenum format
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)
GLuint GLuint GLsizei GLenum 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)