Coverage Report

Created: 2024-08-02 07:04

/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