PlyParser.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /** @file Defines the helper data structures for importing PLY files */
  2. #ifndef AI_PLYFILEHELPER_H_INC
  3. #define AI_PLYFILEHELPER_H_INC
  4. #include <string>
  5. #include <vector>
  6. #include <list>
  7. #include <sstream>
  8. #include "../include/aiTypes.h"
  9. #include "../include/aiMesh.h"
  10. #include "../include/aiAnim.h"
  11. namespace Assimp
  12. {
  13. // http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/
  14. // http://w3.impa.br/~lvelho/outgoing/sossai/old/ViHAP_D4.4.2_PLY_format_v1.1.pdf
  15. // http://www.okino.com/conv/exp_ply.htm
  16. namespace PLY
  17. {
  18. // ---------------------------------------------------------------------------------
  19. /*
  20. name type number of bytes
  21. ---------------------------------------
  22. char character 1
  23. uchar unsigned character 1
  24. short short integer 2
  25. ushort unsigned short integer 2
  26. int integer 4
  27. uint unsigned integer 4
  28. float single-precision float 4
  29. double double-precision float 8
  30. int8
  31. int16
  32. uint8 ... forms are also used
  33. */
  34. enum EDataType
  35. {
  36. EDT_Char = 0x0u,
  37. EDT_UChar,
  38. EDT_Short,
  39. EDT_UShort,
  40. EDT_Int,
  41. EDT_UInt,
  42. EDT_Float,
  43. EDT_Double,
  44. // Marks invalid entries
  45. EDT_INVALID
  46. };
  47. // ---------------------------------------------------------------------------------
  48. /** \brief Specifies semantics for PLY element properties
  49. *
  50. * Semantics define the usage of a property, e.g. x coordinate
  51. */
  52. enum ESemantic
  53. {
  54. //! vertex position x coordinate
  55. EST_XCoord = 0x0u,
  56. //! vertex position x coordinate
  57. EST_YCoord,
  58. //! vertex position x coordinate
  59. EST_ZCoord,
  60. //! vertex normal x coordinate
  61. EST_XNormal,
  62. //! vertex normal y coordinate
  63. EST_YNormal,
  64. //! vertex normal z coordinate
  65. EST_ZNormal,
  66. //! vertex colors, red channel
  67. EST_Red,
  68. //! vertex colors, green channel
  69. EST_Green,
  70. //! vertex colors, blue channel
  71. EST_Blue,
  72. //! vertex colors, alpha channel
  73. EST_Alpha,
  74. //! vertex index list
  75. EST_VertexIndex,
  76. //! texture index
  77. EST_TextureIndex,
  78. //! texture coordinates (stored as element of a face)
  79. EST_TextureCoordinates,
  80. //! material index
  81. EST_MaterialIndex,
  82. //! ambient color, red channel
  83. EST_AmbientRed,
  84. //! ambient color, green channel
  85. EST_AmbientGreen,
  86. //! ambient color, blue channel
  87. EST_AmbientBlue,
  88. //! ambient color, alpha channel
  89. EST_AmbientAlpha,
  90. //! diffuse color, red channel
  91. EST_DiffuseRed,
  92. //! diffuse color, green channel
  93. EST_DiffuseGreen,
  94. //! diffuse color, blue channel
  95. EST_DiffuseBlue,
  96. //! diffuse color, alpha channel
  97. EST_DiffuseAlpha,
  98. //! specular color, red channel
  99. EST_SpecularRed,
  100. //! specular color, green channel
  101. EST_SpecularGreen,
  102. //! specular color, blue channel
  103. EST_SpecularBlue,
  104. //! specular color, alpha channel
  105. EST_SpecularAlpha,
  106. //! specular power for phong shading
  107. EST_PhongPower,
  108. //! opacity between 0 and 1
  109. EST_Opacity,
  110. //! Marks invalid entries
  111. EST_INVALID
  112. };
  113. // ---------------------------------------------------------------------------------
  114. /** \brief Specifies semantics for PLY elements
  115. *
  116. * Semantics define the usage of an element, e.g. vertex or material
  117. */
  118. enum EElementSemantic
  119. {
  120. //! The element is a vertex
  121. EEST_Vertex = 0x0u,
  122. //! The element is a face description (index table)
  123. EEST_Face,
  124. //! The element is a tristrip description (index table)
  125. EEST_TriStrip,
  126. //! The element is an edge description (ignored)
  127. EEST_Edge,
  128. //! The element is a material description
  129. EEST_Material,
  130. //! Marks invalid entries
  131. EEST_INVALID
  132. };
  133. // ---------------------------------------------------------------------------------
  134. /** \brief Helper class for a property in a PLY file.
  135. *
  136. * This can e.g. be a part of the vertex declaration
  137. */
  138. class Property
  139. {
  140. public:
  141. //! Default constructor
  142. Property()
  143. : eType (EDT_Int), bIsList(false), eFirstType(EDT_UChar)
  144. {}
  145. //! Data type of the property
  146. EDataType eType;
  147. //! Semantical meaning of the property
  148. ESemantic Semantic;
  149. //! Of the semantic of the property could not be parsed:
  150. //! Contains the semantic specified in the file
  151. std::string szName;
  152. //! Specifies whether the data type is a list where
  153. //! the first element specifies the size of the list
  154. bool bIsList;
  155. EDataType eFirstType;
  156. //! Parse a property from a string. The end of the
  157. //! string is either '\n', '\r' or '\0'. Return valie is false
  158. //! if the input string is NOT a valid property (E.g. does
  159. //! not start with the "property" keyword)
  160. static bool ParseProperty (const char* p_szIn, const char** p_szOut,
  161. Property* pOut);
  162. //! Parse a data type from a string
  163. static EDataType ParseDataType(const char* p_szIn,const char** p_szOut);
  164. //! Parse a semantic from a string
  165. static ESemantic ParseSemantic(const char* p_szIn,const char** p_szOut);
  166. };
  167. // ---------------------------------------------------------------------------------
  168. /** \brief Helper class for an element in a PLY file.
  169. *
  170. * This can e.g. be the vertex declaration. Elements contain a
  171. * well-defined number of properties.
  172. */
  173. class Element
  174. {
  175. public:
  176. //! Default constructor
  177. Element()
  178. : NumOccur(0), eSemantic (EEST_INVALID)
  179. {}
  180. //! List of properties assigned to the element
  181. //! std::vector to support operator[]
  182. std::vector<Property> alProperties;
  183. //! Semantic of the element
  184. EElementSemantic eSemantic;
  185. //! Of the semantic of the element could not be parsed:
  186. //! Contains the semantic specified in the file
  187. std::string szName;
  188. //! How many times will the element occur?
  189. unsigned int NumOccur;
  190. //! Parse an element from a string.
  191. //! The function will parse all properties contained in the
  192. //! element, too.
  193. static bool ParseElement (const char* p_szIn, const char** p_szOut,
  194. Element* pOut);
  195. //! Parse a semantic from a string
  196. static EElementSemantic ParseSemantic(const char* p_szIn,
  197. const char** p_szOut);
  198. };
  199. // ---------------------------------------------------------------------------------
  200. /** \brief Instance of a property in a PLY file
  201. */
  202. class PropertyInstance
  203. {
  204. public:
  205. //! Default constructor
  206. PropertyInstance ()
  207. {}
  208. union ValueUnion
  209. {
  210. //! uInt32 representation of the property. All
  211. // uint types are automatically converted to uint32
  212. uint32_t iUInt;
  213. //! Int32 representation of the property. All
  214. // int types are automatically converted to int32
  215. int32_t iInt;
  216. //! Float32 representation of the property
  217. float fFloat;
  218. //! Float64 representation of the property
  219. double fDouble;
  220. };
  221. //! List of all values parsed. Contains only one value
  222. // for non-list propertys
  223. std::list<ValueUnion> avList;
  224. //! Parse a property instance
  225. static bool ParseInstance (const char* p_szIn,const char** p_szOut,
  226. const Property* prop, PropertyInstance* p_pcOut);
  227. //! Parse a property instance in binary format
  228. static bool ParseInstanceBinary (const char* p_szIn,const char** p_szOut,
  229. const Property* prop, PropertyInstance* p_pcOut,bool p_bBE);
  230. //! Get the default value for a given data type
  231. static ValueUnion DefaultValue(EDataType eType);
  232. //! Parse a value
  233. static bool ParseValue(const char* p_szIn,const char** p_szOut,
  234. EDataType eType,ValueUnion* out);
  235. //! Parse a binary value
  236. static bool ParseValueBinary(const char* p_szIn,const char** p_szOut,
  237. EDataType eType,ValueUnion* out,bool p_bBE);
  238. //! Convert a property value to a given type TYPE
  239. template <typename TYPE>
  240. static TYPE ConvertTo(ValueUnion v, EDataType eType);
  241. };
  242. // ---------------------------------------------------------------------------------
  243. /** \brief Class for an element instance in a PLY file
  244. */
  245. class ElementInstance
  246. {
  247. public:
  248. //! Default constructor
  249. ElementInstance ()
  250. {}
  251. //! List of all parsed properties
  252. std::vector< PropertyInstance > alProperties;
  253. //! Parse an element instance
  254. static bool ParseInstance (const char* p_szIn,const char** p_szOut,
  255. const Element* pcElement, ElementInstance* p_pcOut);
  256. //! Parse a binary element instance
  257. static bool ParseInstanceBinary (const char* p_szIn,const char** p_szOut,
  258. const Element* pcElement, ElementInstance* p_pcOut,bool p_bBE);
  259. };
  260. // ---------------------------------------------------------------------------------
  261. /** \brief Class for an element instance list in a PLY file
  262. */
  263. class ElementInstanceList
  264. {
  265. public:
  266. //! Default constructor
  267. ElementInstanceList ()
  268. {}
  269. ElementInstanceList (const Element* pc)
  270. {
  271. alInstances.reserve(pc->NumOccur);
  272. }
  273. //! List of all element instances
  274. std::vector< ElementInstance > alInstances;
  275. //! Parse an element instance list
  276. static bool ParseInstanceList (const char* p_szIn,const char** p_szOut,
  277. const Element* pcElement, ElementInstanceList* p_pcOut);
  278. //! Parse a binary element instance list
  279. static bool ParseInstanceListBinary (const char* p_szIn,const char** p_szOut,
  280. const Element* pcElement, ElementInstanceList* p_pcOut,bool p_bBE);
  281. };
  282. // ---------------------------------------------------------------------------------
  283. /** \brief Class to represent the document object model of an ASCII or binary
  284. * (both little and big-endian) PLY file
  285. */
  286. class DOM
  287. {
  288. public:
  289. //! Default constructor
  290. DOM()
  291. {}
  292. std::vector<Element> alElements;
  293. std::vector<ElementInstanceList> alElementData;
  294. //! Parse the DOM for a PLY file. The input string is assumed
  295. //! to be terminated with zero
  296. static bool ParseInstance (const char* p_szIn,DOM* p_pcOut);
  297. static bool ParseInstanceBinary (const char* p_szIn,
  298. DOM* p_pcOut,bool p_bBE);
  299. //! Skip all comment lines after this
  300. static bool SkipComments (const char* p_szIn,const char** p_szOut);
  301. private:
  302. //! Handle the file header and read all element descriptions
  303. bool ParseHeader (const char* p_szIn,const char** p_szOut);
  304. //! Read in all element instance lists
  305. bool ParseElementInstanceLists (const char* p_szIn,const char** p_szOut);
  306. //! Read in all element instance lists for a binary file format
  307. bool ParseElementInstanceListsBinary (const char* p_szIn,
  308. const char** p_szOut,bool p_bBE);
  309. };
  310. // ---------------------------------------------------------------------------------
  311. /** \brief Helper class to represent a loaded face
  312. */
  313. class Face
  314. {
  315. public:
  316. Face()
  317. : iMaterialIndex(0xFFFFFFFF)
  318. {
  319. // set all indices to zero by default
  320. mIndices.resize(3,0);
  321. }
  322. public:
  323. //! List of vertex indices
  324. std::vector<unsigned int> mIndices;
  325. //! Material index
  326. unsigned int iMaterialIndex;
  327. };
  328. // ---------------------------------------------------------------------------------
  329. template <typename TYPE>
  330. TYPE PLY::PropertyInstance::ConvertTo(
  331. PLY::PropertyInstance::ValueUnion v, PLY::EDataType eType)
  332. {
  333. switch (eType)
  334. {
  335. case EDT_Float:
  336. return (TYPE)v.fFloat;
  337. case EDT_Double:
  338. return (TYPE)v.fDouble;
  339. case EDT_UInt:
  340. case EDT_UShort:
  341. case EDT_UChar:
  342. return (TYPE)v.iUInt;
  343. case EDT_Int:
  344. case EDT_Short:
  345. case EDT_Char:
  346. return (TYPE)v.iInt;
  347. };
  348. return (TYPE)0;
  349. }
  350. // ---------------------------------------------------------------------------------
  351. inline bool IsSpace( const char in)
  352. {
  353. return (in == ' ' || in == '\t');
  354. }
  355. // ---------------------------------------------------------------------------------
  356. inline bool IsLineEnd( const char in)
  357. {
  358. return (in == '\r' || in == '\n' || in == '\0');
  359. }
  360. // ---------------------------------------------------------------------------------
  361. inline bool IsSpaceOrNewLine( const char in)
  362. {
  363. return IsSpace(in) || IsLineEnd(in);
  364. }
  365. // ---------------------------------------------------------------------------------
  366. inline bool SkipSpaces( const char* in, const char** out)
  367. {
  368. while (*in == ' ' || *in == '\t')in++;
  369. *out = in;
  370. return !IsLineEnd(*in);
  371. }
  372. // ---------------------------------------------------------------------------------
  373. inline bool SkipLine( const char* in, const char** out)
  374. {
  375. while (*in != '\r' && *in != '\n' && *in != '\0')in++;
  376. if (*in == '\0')
  377. {
  378. *out = in;
  379. return false;
  380. }
  381. in++;
  382. *out = in;
  383. return true;
  384. }
  385. // ---------------------------------------------------------------------------------
  386. inline void SkipSpacesAndLineEnd( const char* in, const char** out)
  387. {
  388. while (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n')in++;
  389. *out = in;
  390. }
  391. };
  392. };
  393. #endif // !! include guard