1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6All rights reserved.
7
8Redistribution and use of this software in source and binary forms,
9with or without modification, are permitted provided that the
10following 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
26THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36OF 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
51namespace Assimp
52{
53
54//pre-declaration
55class 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
60namespace PLY
61{
62
63// ---------------------------------------------------------------------------------
64/*
65name type number of bytes
66---------------------------------------
67char character 1
68uchar unsigned character 1
69short short integer 2
70ushort unsigned short integer 2
71int integer 4
72uint unsigned integer 4
73float single-precision float 4
74double double-precision float 8
75
76int8
77int16
78uint8 ... forms are also used
79*/
80enum 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*/
100enum 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*/
184enum 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 */
213class Property
214{
215public:
216
217 //! Default constructor
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 */
262class Element
263{
264public:
265
266 //! Default constructor
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 */
301class PropertyInstance
302{
303public:
304
305 //! Default constructor
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 */
365class ElementInstance
366{
367public:
368
369 //! Default constructor
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 */
390class ElementInstanceList
391{
392public:
393
394 //! Default constructor
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 */
415class DOM
416{
417public:
418
419 //! Default constructor
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
445private:
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// ---------------------------------------------------------------------------------
461template <typename TYPE>
462inline 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