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