62 #define PLY_BINARY_BE 2 63 #define PLY_BINARY_LE 3 125 : fp(_fp), file_type(0), version(0), which_elem(nullptr)
155 vector<string>
get_words(FILE*,
string&);
171 void store_item(
char*,
int,
int,
unsigned int,
double);
180 void get_ascii_item(
const char*,
int,
int*,
unsigned int*,
double*);
182 FILE*,
int,
int,
int*,
unsigned int*,
double*);
209 if (fp ==
nullptr)
return (
nullptr);
220 plyfile->
elems.resize(elem_names.size());
221 for (
size_t i = 0; i < elem_names.size(); i++)
223 plyfile->
elems[i].name = elem_names[i];
245 const char*
name,
const vector<string>& elem_names,
int file_type,
261 plyfile =
ply_write(fp, elem_names, file_type);
262 if (plyfile ==
nullptr)
return (
nullptr);
284 PlyFile* plyfile,
const string& elem_name,
int nelems,
285 vector<PlyProperty>& prop_list)
290 throw std::runtime_error(
292 "ply_describe_element: can't find element '%s'",
299 const size_t nprops = prop_list.size();
300 elem->
props.resize(nprops);
303 for (
size_t i = 0; i < nprops; i++)
305 elem->
props[i] = prop_list[i];
327 stderr,
"ply_describe_property: can't find element '%s'\n",
333 elem->
props.push_back(*prop);
355 throw std::runtime_error(
357 "ply_element_count: can't find element '%s'",
373 FILE* fp = plyfile->
fp;
380 fprintf(fp,
"format ascii 1.0\n");
383 fprintf(fp,
"format binary_big_endian 1.0\n");
386 fprintf(fp,
"format binary_little_endian 1.0\n");
389 throw std::runtime_error(
391 "ply_header_complete: bad file type = %d",
397 for (
size_t i = 0; i < plyfile->
comments.size(); i++)
402 for (
size_t i = 0; i < plyfile->
obj_info.size(); i++)
407 for (
size_t i = 0; i < plyfile->
elems.size(); i++)
413 for (
size_t j = 0; j < elem->
props.size(); j++)
451 throw std::runtime_error(
453 "ply_elements_setup: can't find element '%s'",
471 FILE* fp = plyfile->
fp;
472 char *elem_data, *item;
476 unsigned int uint_val;
481 elem_data = (
char*)elem_ptr;
482 other_ptr = (
char**)(((
char*)elem_ptr) + elem->
other_offset);
491 for (
size_t j = 0; j < elem->
props.size(); j++)
495 elem_data = *other_ptr;
497 elem_data = (
char*)elem_ptr;
506 const size_t list_count = uint_val;
507 item_ptr = (
char**)(elem_data + prop->
offset);
510 for (
size_t k = 0; k < list_count; k++)
522 item = elem_data + prop->
offset;
538 for (
size_t j = 0; j < elem->
props.size(); j++)
542 elem_data = *other_ptr;
544 elem_data = (
char*)elem_ptr;
554 const size_t list_count = uint_val;
555 item_ptr = (
char**)(elem_data + prop->
offset);
558 for (
size_t k = 0; k < list_count; k++)
570 item = elem_data + prop->
offset;
592 plyfile->
comments.push_back(comment);
606 plyfile->
obj_info.push_back(obj_info);
631 if (fp ==
nullptr)
return (
nullptr);
638 vector<string> words =
get_words(plyfile->
fp, orig_line);
640 if (words.empty() || words[0] !=
"ply")
return nullptr;
642 while (!words.empty())
646 if (words[0] ==
"format")
648 if (words.size() != 3)
return (
nullptr);
649 if (words[1] ==
"ascii")
651 else if (words[1] ==
"binary_big_endian")
653 else if (words[1] ==
"binary_little_endian")
657 plyfile->
version = atof(words[2].c_str());
660 else if (words[0] ==
"element")
662 else if (words[0] ==
"property")
664 else if (words[0] ==
"comment")
666 else if (words[0] ==
"obj_info")
668 else if (words[0] ==
"end_header")
677 for (
size_t i = 0; i < plyfile->
elems.size(); i++)
687 for (
size_t i = 0; i < plyfile->
elems.size(); i++)
688 elem_names.push_back(plyfile->
elems[i].name);
710 const char* filename, vector<string>& elem_names,
int* file_type,
718 fp =
fopen(filename,
"r");
719 if (fp ==
nullptr)
return (
nullptr);
751 PlyFile* plyfile,
const string& elem_name,
int& nelems,
int& nprops)
755 if (elem ==
nullptr)
return vector<PlyProperty>();
758 nprops = elem->
props.size();
790 if (prop_ptr ==
nullptr)
793 stderr,
"Warning: Can't find property '%s' in element '%s'\n",
794 prop->
name.c_str(), elem_name.c_str());
889 if (ply ==
nullptr)
return;
908 for (
size_t i = 0; i < plyfile->
elems.size(); i++)
909 if (element == plyfile->
elems[i].name)
return &plyfile->
elems[i];
929 for (
size_t i = 0; i < elem->
props.size(); i++)
930 if (
string(prop_name) == elem->
props[i].name)
933 return &elem->
props[i];
951 char *elem_data, *item =
nullptr;
955 unsigned int uint_val;
960 char* other_data =
nullptr;
983 vector<string> words =
get_words(plyfile->
fp, orig_line);
986 throw std::runtime_error(
987 format(
"ply_get_element: unexpected end of file"));
991 for (
size_t j = 0; j < elem->
props.size(); j++)
994 store_it = (elem->
store_prop[j] | other_flag);
998 elem_data = elem_ptr;
1000 elem_data = other_data;
1008 &uint_val, &double_val);
1018 list_count = int_val;
1020 store_array = (
char**)(elem_data + prop->
offset);
1022 if (list_count == 0)
1024 if (store_it) *store_array =
nullptr;
1031 (
char*)malloc(
sizeof(
char) * item_size * list_count);
1033 *store_array = item_ptr;
1037 for (
int k = 0; k < list_count; k++)
1041 &int_val, &uint_val, &double_val);
1056 &uint_val, &double_val);
1059 item = elem_data + prop->
offset;
1077 FILE* fp = plyfile->
fp;
1078 char *elem_data, *item =
nullptr;
1082 unsigned int uint_val;
1087 char* other_data =
nullptr;
1102 other_data = (
char*)malloc(elem->
other_size);
1112 for (
size_t j = 0; j < elem->
props.size(); j++)
1115 store_it = (elem->
store_prop[j] | other_flag);
1119 elem_data = elem_ptr;
1121 elem_data = other_data;
1129 &uint_val, &double_val))
1134 "RPly::binary_get_element: Error reading binary file!\n");
1146 list_count = int_val;
1155 store_array = (
char**)(elem_data + prop->
offset);
1156 if (list_count == 0)
1158 if (store_it) *store_array =
nullptr;
1165 (
char*)malloc(
sizeof(
char) * item_size * list_count);
1167 *store_array = item_ptr;
1171 for (
int k = 0; k < list_count; k++)
1175 &uint_val, &double_val))
1180 "RPly::binary_get_element: Error reading binary " 1197 fp, bin_file_type, prop->
external_type, &int_val, &uint_val,
1203 "RPly::binary_get_element: Error reading binary file!\n");
1208 item = elem_data + prop->
offset;
1229 throw std::runtime_error(
1230 format(
"write_scalar_type: bad data code = %d",
code));
1254 #define BIG_STRING 4096 1257 vector<string> words;
1263 if (result ==
nullptr)
1288 unsigned char* puchar;
1291 unsigned short int* pushort;
1293 unsigned int* puint;
1297 unsigned int uint_value;
1298 double double_value;
1303 pchar = (
char*)item;
1305 return ((
double)int_value);
1307 puchar = (
unsigned char*)item;
1308 int_value = *puchar;
1309 return ((
double)int_value);
1311 pshort = (
short int*)item;
1312 int_value = *pshort;
1313 return ((
double)int_value);
1315 pushort = (
unsigned short int*)item;
1316 int_value = *pushort;
1317 return ((
double)int_value);
1321 return ((
double)int_value);
1323 puint = (
unsigned int*)item;
1324 uint_value = *puint;
1325 return ((
double)uint_value);
1327 pfloat = (
float*)item;
1328 double_value = *pfloat;
1329 return (double_value);
1331 pdouble = (
double*)item;
1332 double_value = *pdouble;
1333 return (double_value);
1335 throw std::runtime_error(
1336 format(
"get_item_value: bad type = %d",
type));
1352 FILE* fp,
int int_val,
unsigned int uint_val,
double double_val,
int type)
1354 unsigned char uchar_val;
1356 unsigned short ushort_val;
1364 fwrite(&char_val, 1, 1, fp);
1367 short_val = int_val;
1368 fwrite(&short_val, 2, 1, fp);
1371 fwrite(&int_val, 4, 1, fp);
1374 uchar_val = uint_val;
1375 fwrite(&uchar_val, 1, 1, fp);
1378 ushort_val = uint_val;
1379 fwrite(&ushort_val, 2, 1, fp);
1382 fwrite(&uint_val, 4, 1, fp);
1385 float_val = double_val;
1386 fwrite(&float_val, 4, 1, fp);
1389 fwrite(&double_val, 8, 1, fp);
1392 throw std::runtime_error(
1393 format(
"write_binary_item: bad type = %d",
type));
1409 FILE* fp,
int int_val,
unsigned int uint_val,
double double_val,
int type)
1425 fprintf(fp,
"%g ", double_val);
1428 throw std::runtime_error(
1429 format(
"write_ascii_item: bad type = %d",
type));
1448 void* ptr,
int type,
int* int_val,
unsigned int* uint_val,
1454 *int_val = *((
char*)ptr);
1455 *uint_val = *int_val;
1456 *double_val = *int_val;
1459 *uint_val = *((
unsigned char*)ptr);
1460 *int_val = *uint_val;
1461 *double_val = *uint_val;
1464 *int_val = *((
short int*)ptr);
1465 *uint_val = *int_val;
1466 *double_val = *int_val;
1469 *uint_val = *((
unsigned short int*)ptr);
1470 *int_val = *uint_val;
1471 *double_val = *uint_val;
1474 *int_val = *((
int*)ptr);
1475 *uint_val = *int_val;
1476 *double_val = *int_val;
1479 *uint_val = *((
unsigned int*)ptr);
1480 *int_val = *uint_val;
1481 *double_val = *uint_val;
1484 *double_val = *((
float*)ptr);
1485 *int_val = *double_val;
1486 *uint_val = *double_val;
1489 *double_val = *((
double*)ptr);
1490 *int_val = *double_val;
1491 *uint_val = *double_val;
1494 throw std::runtime_error(
1495 format(
"get_stored_item: bad type = %d",
type));
1516 FILE* fp,
int bin_file_type,
int type,
int* int_val,
unsigned int* uint_val,
1527 if (fread(ptr, 1, 1, fp) != 1)
return 0;
1528 *int_val = *((
char*)ptr);
1529 *uint_val = *int_val;
1530 *double_val = *int_val;
1533 if (fread(ptr, 1, 1, fp) != 1)
return 0;
1534 *uint_val = *((
unsigned char*)ptr);
1535 *int_val = *uint_val;
1536 *double_val = *uint_val;
1539 if (fread(ptr, 2, 1, fp) != 1)
return 0;
1540 *int_val = *((
short int*)ptr);
1541 *uint_val = *int_val;
1542 *double_val = *int_val;
1545 if (fread(ptr, 2, 1, fp) != 1)
return 0;
1546 *uint_val = *((
unsigned short int*)ptr);
1547 *int_val = *uint_val;
1548 *double_val = *uint_val;
1551 if (fread(ptr, 4, 1, fp) != 1)
return 0;
1552 *int_val = *((
int*)ptr);
1553 *uint_val = *int_val;
1554 *double_val = *int_val;
1557 if (fread(ptr, 4, 1, fp) != 1)
return 0;
1558 *uint_val = *((
unsigned int*)ptr);
1559 *int_val = *uint_val;
1560 *double_val = *uint_val;
1563 if (fread(ptr, 4, 1, fp) != 1)
return 0;
1564 *double_val = *((
float*)ptr);
1565 *int_val = *double_val;
1566 *uint_val = *double_val;
1569 if (fread(ptr, 8, 1, fp) != 1)
return 0;
1570 *double_val = *((
double*)ptr);
1571 *int_val = *double_val;
1572 *uint_val = *double_val;
1575 throw std::runtime_error(
1576 format(
"get_binary_item: bad type = %d",
type));
1582 #if MRPT_IS_BIG_ENDIAN 1590 int int_val2 = *int_val;
1591 unsigned int uint_val2 = *uint_val;
1592 double double_val2 = *double_val;
1616 const char* word,
int type,
int* int_val,
unsigned int* uint_val,
1626 *int_val = atoi(word);
1627 *uint_val = *int_val;
1628 *double_val = *int_val;
1632 *uint_val = strtoul(word, (
char**)
nullptr, 10);
1633 *int_val = *uint_val;
1634 *double_val = *uint_val;
1639 *double_val = atof(word);
1640 *int_val = (int)*double_val;
1641 *uint_val = (
unsigned int)*double_val;
1645 throw std::runtime_error(
1646 format(
"get_ascii_item: bad type = %d",
type));
1665 char* item,
int type,
int int_val,
unsigned int uint_val,
double double_val)
1667 unsigned char* puchar;
1669 unsigned short int* pushort;
1671 unsigned int* puint;
1681 puchar = (
unsigned char*)item;
1685 pshort = (
short*)item;
1689 pushort = (
unsigned short*)item;
1690 *pushort = uint_val;
1697 puint = (
unsigned int*)item;
1701 pfloat = (
float*)item;
1702 *pfloat = double_val;
1705 pdouble = (
double*)item;
1706 *pdouble = double_val;
1709 throw std::runtime_error(
format(
"store_item: bad type = %d",
type));
1728 elem->
name = words[1];
1729 elem->
num = atoi(words[2].c_str());
1773 if (words[1] ==
"list")
1777 prop->
name = words[4];
1783 prop->
name = words[2];
1857 bool PLY_Importer::loadFromPlyFile(
1858 const std::string& filename, std::vector<std::string>* file_comments,
1859 std::vector<std::string>* file_obj_info)
1864 vector<string> elist;
1873 for (
size_t i = 0; i < elist.size(); i++)
1876 const string& elem_name = elist[i];
1877 int num_elems = 0, nprops = 0;
1886 if (
"vertex" == elem_name)
1894 this->PLY_import_set_vertex_count(num_elems);
1895 for (
int j = 0; j < num_elems; j++)
1908 this->PLY_import_set_vertex(j, xyz, &col);
1915 this->PLY_import_set_vertex(j, xyz, &col);
1919 this->PLY_import_set_vertex(j, xyz);
1932 vector<string> strs;
1934 *file_comments = std::vector<std::string>(strs);
1940 vector<string> strs;
1942 *file_obj_info = std::vector<std::string>(strs);
1952 catch (std::exception& e)
1960 bool PLY_Exporter::saveToPlyFile(
1962 const std::vector<std::string>& file_comments,
1963 const std::vector<std::string>& file_obj_info)
const 1968 vector<string> elem_names;
1969 elem_names.push_back(
string(
"vertex"));
1970 elem_names.push_back(
string(
"face"));
1982 filename.c_str(), elem_names, save_in_binary ?
1983 #if MRPT_IS_BIG_ENDIAN 1993 const size_t nverts = this->PLY_export_get_vertex_count();
1994 const size_t nfaces = this->PLY_export_get_face_count();
2002 this->PLY_export_get_vertex(0, pt, pt_has_color, pt_color);
2019 for (
size_t k = 0; k < file_comments.size(); k++)
2022 for (
size_t k = 0; k < file_obj_info.size(); k++)
2031 for (
size_t i = 0; i < nverts; i++)
2036 this->PLY_export_get_vertex(i, pt, pt_has_color, pt_color);
2045 (1.0f / 3.0f) * (pt_color.
R + pt_color.
G + pt_color.
B);
2068 catch (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)