1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
4
5 Copyright (c) 2006-2017, assimp team
6 All rights reserved.
7
8 Redistribution and use of this software in source and binary forms,
9 with or without modification, are permitted provided that the
10 following conditions are met:
11
12 * Redistributions of source code must retain the above
13 copyright notice, this list of conditions and the
14 following disclaimer.
15
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
20
21 * Neither the name of the assimp team, nor the names of its
22 contributors may be used to endorse or promote products
23 derived from this software without specific prior
24 written permission of the assimp team.
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
38 ----------------------------------------------------------------------
39 */
40
41
42 /** @file Defines the helper data structures for importing PLY files */
43 #ifndef AI_PLYFILEHELPER_H_INC
44 #define AI_PLYFILEHELPER_H_INC
45
46
47 #include "ParsingUtils.h"
48 #include "IOStreamBuffer.h"
49 #include <vector>
50
51 namespace Assimp
52 {
53
54 //pre-declaration
55 class PLYImporter;
56
57 // http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/
58 // http://w3.impa.br/~lvelho/outgoing/sossai/old/ViHAP_D4.4.2_PLY_format_v1.1.pdf
59 // http://www.okino.com/conv/exp_ply.htm
60 namespace PLY
61 {
62
63 // ---------------------------------------------------------------------------------
64 /*
65 name type number of bytes
66 ---------------------------------------
67 char character 1
68 uchar unsigned character 1
69 short short integer 2
70 ushort unsigned short integer 2
71 int integer 4
72 uint unsigned integer 4
73 float single-precision float 4
74 double double-precision float 8
75
76 int8
77 int16
78 uint8 ... forms are also used
79 */
80 enum EDataType
81 {
82 EDT_Char = 0x0u,
83 EDT_UChar,
84 EDT_Short,
85 EDT_UShort,
86 EDT_Int,
87 EDT_UInt,
88 EDT_Float,
89 EDT_Double,
90
91 // Marks invalid entries
92 EDT_INVALID
93 };
94
95 // ---------------------------------------------------------------------------------
96 /** \brief Specifies semantics for PLY element properties
97 *
98 * Semantics define the usage of a property, e.g. x coordinate
99 */
100 enum ESemantic
101 {
102 //! vertex position x coordinate
103 EST_XCoord = 0x0u,
104 //! vertex position x coordinate
105 EST_YCoord,
106 //! vertex position x coordinate
107 EST_ZCoord,
108
109 //! vertex normal x coordinate
110 EST_XNormal,
111 //! vertex normal y coordinate
112 EST_YNormal,
113 //! vertex normal z coordinate
114 EST_ZNormal,
115
116 //! u texture coordinate
117 EST_UTextureCoord,
118 //! v texture coordinate
119 EST_VTextureCoord,
120
121 //! vertex colors, red channel
122 EST_Red,
123 //! vertex colors, green channel
124 EST_Green,
125 //! vertex colors, blue channel
126 EST_Blue,
127 //! vertex colors, alpha channel
128 EST_Alpha,
129
130 //! vertex index list
131 EST_VertexIndex,
132
133 //! texture index
134 EST_TextureIndex,
135
136 //! texture coordinates (stored as element of a face)
137 EST_TextureCoordinates,
138
139 //! material index
140 EST_MaterialIndex,
141
142 //! ambient color, red channel
143 EST_AmbientRed,
144 //! ambient color, green channel
145 EST_AmbientGreen,
146 //! ambient color, blue channel
147 EST_AmbientBlue,
148 //! ambient color, alpha channel
149 EST_AmbientAlpha,
150
151 //! diffuse color, red channel
152 EST_DiffuseRed,
153 //! diffuse color, green channel
154 EST_DiffuseGreen,
155 //! diffuse color, blue channel
156 EST_DiffuseBlue,
157 //! diffuse color, alpha channel
158 EST_DiffuseAlpha,
159
160 //! specular color, red channel
161 EST_SpecularRed,
162 //! specular color, green channel
163 EST_SpecularGreen,
164 //! specular color, blue channel
165 EST_SpecularBlue,
166 //! specular color, alpha channel
167 EST_SpecularAlpha,
168
169 //! specular power for phong shading
170 EST_PhongPower,
171
172 //! opacity between 0 and 1
173 EST_Opacity,
174
175 //! Marks invalid entries
176 EST_INVALID
177 };
178
179 // ---------------------------------------------------------------------------------
180 /** \brief Specifies semantics for PLY elements
181 *
182 * Semantics define the usage of an element, e.g. vertex or material
183 */
184 enum EElementSemantic
185 {
186 //! The element is a vertex
187 EEST_Vertex = 0x0u,
188
189 //! The element is a face description (index table)
190 EEST_Face,
191
192 //! The element is a tristrip description (index table)
193 EEST_TriStrip,
194
195 //! The element is an edge description (ignored)
196 EEST_Edge,
197
198 //! The element is a material description
199 EEST_Material,
200
201 //! texture path
202 EEST_TextureFile,
203
204 //! Marks invalid entries
205 EEST_INVALID
206 };
207
208 // ---------------------------------------------------------------------------------
209 /** \brief Helper class for a property in a PLY file.
210 *
211 * This can e.g. be a part of the vertex declaration
212 */
213 class Property
214 {
215 public:
216
217 //! Default constructor
Property()218 Property()
219 : eType (EDT_Int),
220 Semantic(),
221 bIsList(false),
222 eFirstType(EDT_UChar)
223 {}
224
225 //! Data type of the property
226 EDataType eType;
227
228 //! Semantical meaning of the property
229 ESemantic Semantic;
230
231 //! Of the semantic of the property could not be parsed:
232 //! Contains the semantic specified in the file
233 std::string szName;
234
235 //! Specifies whether the data type is a list where
236 //! the first element specifies the size of the list
237 bool bIsList;
238 EDataType eFirstType;
239
240 // -------------------------------------------------------------------
241 //! Parse a property from a string. The end of the
242 //! string is either '\n', '\r' or '\0'. Return value is false
243 //! if the input string is NOT a valid property (E.g. does
244 //! not start with the "property" keyword)
245 static bool ParseProperty(std::vector<char> &buffer, Property* pOut);
246
247 // -------------------------------------------------------------------
248 //! Parse a data type from a string
249 static EDataType ParseDataType(std::vector<char> &buffer);
250
251 // -------------------------------------------------------------------
252 //! Parse a semantic from a string
253 static ESemantic ParseSemantic(std::vector<char> &buffer);
254 };
255
256 // ---------------------------------------------------------------------------------
257 /** \brief Helper class for an element in a PLY file.
258 *
259 * This can e.g. be the vertex declaration. Elements contain a
260 * well-defined number of properties.
261 */
262 class Element
263 {
264 public:
265
266 //! Default constructor
Element()267 Element()
268 : eSemantic (EEST_INVALID)
269 , NumOccur(0)
270 {}
271
272 //! List of properties assigned to the element
273 //! std::vector to support operator[]
274 std::vector<Property> alProperties;
275
276 //! Semantic of the element
277 EElementSemantic eSemantic;
278
279 //! Of the semantic of the element could not be parsed:
280 //! Contains the semantic specified in the file
281 std::string szName;
282
283 //! How many times will the element occur?
284 unsigned int NumOccur;
285
286
287 // -------------------------------------------------------------------
288 //! Parse an element from a string.
289 //! The function will parse all properties contained in the
290 //! element, too.
291 static bool ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, Element* pOut);
292
293 // -------------------------------------------------------------------
294 //! Parse a semantic from a string
295 static EElementSemantic ParseSemantic(std::vector<char> &buffer);
296 };
297
298 // ---------------------------------------------------------------------------------
299 /** \brief Instance of a property in a PLY file
300 */
301 class PropertyInstance
302 {
303 public:
304
305 //! Default constructor
PropertyInstance()306 PropertyInstance ()
307 {}
308
309 union ValueUnion
310 {
311
312 //! uInt32 representation of the property. All
313 // uint types are automatically converted to uint32
314 uint32_t iUInt;
315
316 //! Int32 representation of the property. All
317 // int types are automatically converted to int32
318 int32_t iInt;
319
320 //! Float32 representation of the property
321 float fFloat;
322
323 //! Float64 representation of the property
324 double fDouble;
325
326 };
327
328 // -------------------------------------------------------------------
329 //! List of all values parsed. Contains only one value
330 // for non-list properties
331 std::vector<ValueUnion> avList;
332
333 // -------------------------------------------------------------------
334 //! Parse a property instance
335 static bool ParseInstance(const char* &pCur,
336 const Property* prop, PropertyInstance* p_pcOut);
337
338 // -------------------------------------------------------------------
339 //! Parse a property instance in binary format
340 static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
341 const char* &pCur, unsigned int &bufferSize, const Property* prop, PropertyInstance* p_pcOut, bool p_bBE);
342
343 // -------------------------------------------------------------------
344 //! Get the default value for a given data type
345 static ValueUnion DefaultValue(EDataType eType);
346
347 // -------------------------------------------------------------------
348 //! Parse a value
349 static bool ParseValue(const char* &pCur, EDataType eType, ValueUnion* out);
350
351 // -------------------------------------------------------------------
352 //! Parse a binary value
353 static bool ParseValueBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
354 const char* &pCur, unsigned int &bufferSize, EDataType eType, ValueUnion* out, bool p_bBE);
355
356 // -------------------------------------------------------------------
357 //! Convert a property value to a given type TYPE
358 template <typename TYPE>
359 static TYPE ConvertTo(ValueUnion v, EDataType eType);
360 };
361
362 // ---------------------------------------------------------------------------------
363 /** \brief Class for an element instance in a PLY file
364 */
365 class ElementInstance
366 {
367 public:
368
369 //! Default constructor
ElementInstance()370 ElementInstance ()
371 {}
372
373 //! List of all parsed properties
374 std::vector< PropertyInstance > alProperties;
375
376 // -------------------------------------------------------------------
377 //! Parse an element instance
378 static bool ParseInstance(const char* &pCur,
379 const Element* pcElement, ElementInstance* p_pcOut);
380
381 // -------------------------------------------------------------------
382 //! Parse a binary element instance
383 static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
384 const char* &pCur, unsigned int &bufferSize, const Element* pcElement, ElementInstance* p_pcOut, bool p_bBE);
385 };
386
387 // ---------------------------------------------------------------------------------
388 /** \brief Class for an element instance list in a PLY file
389 */
390 class ElementInstanceList
391 {
392 public:
393
394 //! Default constructor
ElementInstanceList()395 ElementInstanceList ()
396 {}
397
398 //! List of all element instances
399 std::vector< ElementInstance > alInstances;
400
401 // -------------------------------------------------------------------
402 //! Parse an element instance list
403 static bool ParseInstanceList(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
404 const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader);
405
406 // -------------------------------------------------------------------
407 //! Parse a binary element instance list
408 static bool ParseInstanceListBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
409 const char* &pCur, unsigned int &bufferSize, const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader, bool p_bBE);
410 };
411 // ---------------------------------------------------------------------------------
412 /** \brief Class to represent the document object model of an ASCII or binary
413 * (both little and big-endian) PLY file
414 */
415 class DOM
416 {
417 public:
418
419 //! Default constructor
DOM()420 DOM()
421 {}
422
423
424 //! Contains all elements of the file format
425 std::vector<Element> alElements;
426 //! Contains the real data of each element's instance list
427 std::vector<ElementInstanceList> alElementData;
428
429 //! Parse the DOM for a PLY file. The input string is assumed
430 //! to be terminated with zero
431 static bool ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader);
432 static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader, bool p_bBE);
433
434 //! Skip all comment lines after this
435 static bool SkipComments(std::vector<char> &buffer);
436
437 static bool SkipSpaces(std::vector<char> &buffer);
438
439 static bool SkipLine(std::vector<char> &buffer);
440
441 static bool TokenMatch(std::vector<char> &buffer, const char* token, unsigned int len);
442
443 static bool SkipSpacesAndLineEnd(std::vector<char> &buffer);
444
445 private:
446
447 // -------------------------------------------------------------------
448 //! Handle the file header and read all element descriptions
449 bool ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, bool p_bBE);
450
451 // -------------------------------------------------------------------
452 //! Read in all element instance lists
453 bool ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, PLYImporter* loader);
454
455 // -------------------------------------------------------------------
456 //! Read in all element instance lists for a binary file format
457 bool ParseElementInstanceListsBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, const char* &pCur, unsigned int &bufferSize, PLYImporter* loader, bool p_bBE);
458 };
459
460 // ---------------------------------------------------------------------------------
461 template <typename TYPE>
ConvertTo(PLY::PropertyInstance::ValueUnion v,PLY::EDataType eType)462 inline TYPE PLY::PropertyInstance::ConvertTo(
463 PLY::PropertyInstance::ValueUnion v, PLY::EDataType eType)
464 {
465 switch (eType)
466 {
467 case EDT_Float:
468 return (TYPE)v.fFloat;
469 case EDT_Double:
470 return (TYPE)v.fDouble;
471
472 case EDT_UInt:
473 case EDT_UShort:
474 case EDT_UChar:
475 return (TYPE)v.iUInt;
476
477 case EDT_Int:
478 case EDT_Short:
479 case EDT_Char:
480 return (TYPE)v.iInt;
481 default: ;
482 };
483 return (TYPE)0;
484 }
485
486 } // Namespace PLY
487 } // Namespace AssImp
488
489 #endif // !! include guard
490