1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14copyright notice, this list of conditions and the
15following disclaimer.
16
17* Redistributions in binary form must reproduce the above
18copyright notice, this list of conditions and the
19following disclaimer in the documentation and/or other
20materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23contributors may be used to endorse or promote products
24derived from this software without specific prior
25written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41/// \file X3DImporter.hpp
42/// \brief X3D-format files importer for Assimp.
43/// \date 2015-2016
44/// \author smal.root@gmail.com
45// Thanks to acorn89 for support.
46
47#ifndef INCLUDED_AI_X3D_IMPORTER_H
48#define INCLUDED_AI_X3D_IMPORTER_H
49
50#include "X3DImporter_Node.hpp"
51
52// Header files, Assimp.
53#include <assimp/DefaultLogger.hpp>
54#include <assimp/importerdesc.h>
55#include <assimp/ProgressHandler.hpp>
56#include <assimp/types.h>
57#include "BaseImporter.h"
58#include "irrXMLWrapper.h"
59#include "FIReader.hpp"
60//#include <regex>
61
62namespace Assimp {
63
64/// \class X3DImporter
65/// Class that holding scene graph which include: groups, geometry, metadata etc.
66///
67/// Limitations.
68///
69/// Pay attention that X3D is format for interactive graphic and simulations for web browsers.
70/// So not all features can be imported using Assimp.
71///
72/// Unsupported nodes:
73/// CAD geometry component:
74/// "CADAssembly", "CADFace", "CADLayer", "CADPart", "IndexedQuadSet", "QuadSet"
75/// Core component:
76/// "ROUTE", "ExternProtoDeclare", "ProtoDeclare", "ProtoInstance", "ProtoInterface", "WorldInfo"
77/// Distributed interactive simulation (DIS) component:
78/// "DISEntityManager", "DISEntityTypeMapping", "EspduTransform", "ReceiverPdu", "SignalPdu", "TransmitterPdu"
79/// Cube map environmental texturing component:
80/// "ComposedCubeMapTexture", "GeneratedCubeMapTexture", "ImageCubeMapTexture"
81/// Environmental effects component:
82/// "Background", "Fog", "FogCoordinate", "LocalFog", "TextureBackground"
83/// Environmental sensor component:
84/// "ProximitySensor", "TransformSensor", "VisibilitySensor"
85/// Followers component:
86/// "ColorChaser", "ColorDamper", "CoordinateChaser", "CoordinateDamper", "OrientationChaser", "OrientationDamper", "PositionChaser",
87/// "PositionChaser2D", "PositionDamper", "PositionDamper2D", "ScalarChaser", "ScalarDamper", "TexCoordChaser2D", "TexCoordDamper2D"
88/// Geospatial component:
89/// "GeoCoordinate", "GeoElevationGrid", "GeoLocation", "GeoLOD", "GeoMetadata", "GeoOrigin", "GeoPositionInterpolator", "GeoProximitySensor",
90/// "GeoTouchSensor", "GeoTransform", "GeoViewpoint"
91/// Humanoid Animation (H-Anim) component:
92/// "HAnimDisplacer", "HAnimHumanoid", "HAnimJoint", "HAnimSegment", "HAnimSite"
93/// Interpolation component:
94/// "ColorInterpolator", "CoordinateInterpolator", "CoordinateInterpolator2D", "EaseInEaseOut", "NormalInterpolator", "OrientationInterpolator",
95/// "PositionInterpolator", "PositionInterpolator2D", "ScalarInterpolator", "SplinePositionInterpolator", "SplinePositionInterpolator2D",
96/// "SplineScalarInterpolator", "SquadOrientationInterpolator",
97/// Key device sensor component:
98/// "KeySensor", "StringSensor"
99/// Layering component:
100/// "Layer", "LayerSet", "Viewport"
101/// Layout component:
102/// "Layout", "LayoutGroup", "LayoutLayer", "ScreenFontStyle", "ScreenGroup"
103/// Navigation component:
104/// "Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup"
105/// Networking component:
106/// "EXPORT", "IMPORT", "Anchor", "LoadSensor"
107/// NURBS component:
108/// "Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface",
109/// "NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate",
110/// "NurbsTrimmedSurface"
111/// Particle systems component:
112/// "BoundedPhysicsModel", "ConeEmitter", "ExplosionEmitter", "ForcePhysicsModel", "ParticleSystem", "PointEmitter", "PolylineEmitter",
113/// "SurfaceEmitter", "VolumeEmitter", "WindPhysicsModel"
114/// Picking component:
115/// "LinePickSensor", "PickableGroup", "PointPickSensor", "PrimitivePickSensor", "VolumePickSensor"
116/// Pointing device sensor component:
117/// "CylinderSensor", "PlaneSensor", "SphereSensor", "TouchSensor"
118/// Rendering component:
119/// "ClipPlane"
120/// Rigid body physics:
121/// "BallJoint", "CollidableOffset", "CollidableShape", "CollisionCollection", "CollisionSensor", "CollisionSpace", "Contact", "DoubleAxisHingeJoint",
122/// "MotorJoint", "RigidBody", "RigidBodyCollection", "SingleAxisHingeJoint", "SliderJoint", "UniversalJoint"
123/// Scripting component:
124/// "Script"
125/// Programmable shaders component:
126/// "ComposedShader", "FloatVertexAttribute", "Matrix3VertexAttribute", "Matrix4VertexAttribute", "PackagedShader", "ProgramShader", "ShaderPart",
127/// "ShaderProgram",
128/// Shape component:
129/// "FillProperties", "LineProperties", "TwoSidedMaterial"
130/// Sound component:
131/// "AudioClip", "Sound"
132/// Text component:
133/// "FontStyle", "Text"
134/// Texturing3D Component:
135/// "ComposedTexture3D", "ImageTexture3D", "PixelTexture3D", "TextureCoordinate3D", "TextureCoordinate4D", "TextureTransformMatrix3D",
136/// "TextureTransform3D"
137/// Texturing component:
138/// "MovieTexture", "MultiTexture", "MultiTextureCoordinate", "MultiTextureTransform", "PixelTexture", "TextureCoordinateGenerator",
139/// "TextureProperties",
140/// Time component:
141/// "TimeSensor"
142/// Event Utilities component:
143/// "BooleanFilter", "BooleanSequencer", "BooleanToggle", "BooleanTrigger", "IntegerSequencer", "IntegerTrigger", "TimeTrigger",
144/// Volume rendering component:
145/// "BlendedVolumeStyle", "BoundaryEnhancementVolumeStyle", "CartoonVolumeStyle", "ComposedVolumeStyle", "EdgeEnhancementVolumeStyle",
146/// "IsoSurfaceVolumeData", "OpacityMapVolumeStyle", "ProjectionVolumeStyle", "SegmentedVolumeData", "ShadedVolumeStyle",
147/// "SilhouetteEnhancementVolumeStyle", "ToneMappedVolumeStyle", "VolumeData"
148///
149/// Supported nodes:
150/// Core component:
151/// "MetadataBoolean", "MetadataDouble", "MetadataFloat", "MetadataInteger", "MetadataSet", "MetadataString"
152/// Geometry2D component:
153/// "Arc2D", "ArcClose2D", "Circle2D", "Disk2D", "Polyline2D", "Polypoint2D", "Rectangle2D", "TriangleSet2D"
154/// Geometry3D component:
155/// "Box", "Cone", "Cylinder", "ElevationGrid", "Extrusion", "IndexedFaceSet", "Sphere"
156/// Grouping component:
157/// "Group", "StaticGroup", "Switch", "Transform"
158/// Lighting component:
159/// "DirectionalLight", "PointLight", "SpotLight"
160/// Networking component:
161/// "Inline"
162/// Rendering component:
163/// "Color", "ColorRGBA", "Coordinate", "IndexedLineSet", "IndexedTriangleFanSet", "IndexedTriangleSet", "IndexedTriangleStripSet", "LineSet",
164/// "PointSet", "TriangleFanSet", "TriangleSet", "TriangleStripSet", "Normal"
165/// Shape component:
166/// "Shape", "Appearance", "Material"
167/// Texturing component:
168/// "ImageTexture", "TextureCoordinate", "TextureTransform"
169///
170/// Limitations of attribute "USE".
171/// If "USE" is set then node must be empty, like that:
172/// <Node USE='name'/>
173/// not the
174/// <Node USE='name'><!-- something --> </Node>
175///
176/// Ignored attributes: "creaseAngle", "convex", "solid".
177///
178/// Texture coordinates generating: only for Sphere, Cone, Cylinder. In all other case used PLANE mapping.
179/// It's better that Assimp main code has powerful texture coordinates generator. Then is not needed to
180/// duplicate this code in every importer.
181///
182/// Lighting limitations.
183/// If light source placed in some group with "DEF" set. And after that some node is use it group with "USE" attribute then
184/// you will get error about duplicate light sources. That's happening because Assimp require names for lights but do not like
185/// duplicates of it )).
186///
187/// Color for faces.
188/// That's happening when attribute "colorPerVertex" is set to "false". But Assimp do not hold how many colors has mesh and require
189/// equal length for mVertices and mColors. You will see the colors but vertices will use call which last used in "colorIdx".
190///
191/// That's all for now. Enjoy
192///
193class X3DImporter : public BaseImporter
194{
195public:
196 std::list<CX3DImporter_NodeElement*> NodeElement_List;///< All elements of scene graph.
197
198public:
199 /***********************************************/
200 /****************** Functions ******************/
201 /***********************************************/
202
203 /// Default constructor.
204 X3DImporter();
205
206 /// Default destructor.
207 ~X3DImporter();
208
209 /***********************************************/
210 /******** Functions: parse set, public *********/
211 /***********************************************/
212
213 /// Parse X3D file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
214 /// Also exception can be thrown if trouble will found.
215 /// \param [in] pFile - name of file to be parsed.
216 /// \param [in] pIOHandler - pointer to IO helper object.
217 void ParseFile( const std::string& pFile, IOSystem* pIOHandler );
218
219 /***********************************************/
220 /********* Functions: BaseImporter set *********/
221 /***********************************************/
222
223 bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig ) const;
224 void GetExtensionList( std::set<std::string>& pExtensionList );
225 void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler );
226 const aiImporterDesc* GetInfo()const;
227
228
229private:
230 /// Disabled copy constructor.
231 X3DImporter(const X3DImporter& pScene);
232
233 /// Disabled assign operator.
234 X3DImporter& operator=(const X3DImporter& pScene);
235
236 /// Clear all temporary data.
237 void Clear();
238
239 /***********************************************/
240 /************* Functions: find set *************/
241 /***********************************************/
242
243 /// Find requested node element. Search will be made in all existing nodes.
244 /// \param [in] pID - ID of requested element.
245 /// \param [in] pType - type of requested element.
246 /// \param [out] pElement - pointer to pointer to item found.
247 /// \return true - if the element is found, else - false.
248 bool FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement);
249
250 /// Find requested node element. Search will be made from pointed node down to childs.
251 /// \param [in] pStartNode - pointer to start node.
252 /// \param [in] pID - ID of requested element.
253 /// \param [in] pType - type of requested element.
254 /// \param [out] pElement - pointer to pointer to item found.
255 /// \return true - if the element is found, else - false.
256 bool FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, const std::string& pID, const CX3DImporter_NodeElement::EType pType,
257 CX3DImporter_NodeElement** pElement);
258
259 /// Find requested node element. For "Node"'s accounting flag "Static".
260 /// \param [in] pName - name of requested element.
261 /// \param [in] pType - type of requested element.
262 /// \param [out] pElement - pointer to pointer to item found.
263 /// \return true - if the element is found, else - false.
264 bool FindNodeElement(const std::string& pName, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement);
265
266 /***********************************************/
267 /********* Functions: postprocess set **********/
268 /***********************************************/
269
270 /// \return transformation matrix from global coordinate system to local.
271 aiMatrix4x4 PostprocessHelper_Matrix_GlobalToCurrent() const;
272
273 /// Check if child elements of node element is metadata and add it to temporary list.
274 /// \param [in] pNodeElement - node element where metadata is searching.
275 /// \param [out] pList - temporary list for collected metadata.
276 void PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const;
277
278 /// Check if type of node element is metadata. E.g. <MetadataSet>, <MetadataString>.
279 /// \param [in] pType - checked type.
280 /// \return true - if the type corresponds to the metadata.
281 bool PostprocessHelper_ElementIsMetadata(const CX3DImporter_NodeElement::EType pType) const;
282
283 /// Check if type of node element is geometry object and can be used to build mesh. E.g. <Box>, <Arc2D>.
284 /// \param [in] pType - checked type.
285 /// \return true - if the type corresponds to the mesh.
286 bool PostprocessHelper_ElementIsMesh(const CX3DImporter_NodeElement::EType pType) const;
287
288 /// Read CX3DImporter_NodeElement_Light, create aiLight and add it to list of the lights.
289 /// \param [in] pNodeElement - reference to lisght element(<DirectionalLight>, <PointLight>, <SpotLight>).
290 /// \param [out] pSceneLightList - reference to list of the lights.
291 void Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeElement, std::list<aiLight*>& pSceneLightList) const;
292
293 /// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract
294 /// all needed data from scene graph.
295 /// \param [in] pNodeElement - reference to material element(<Appearance>).
296 /// \param [out] pMaterial - pointer to pointer to created material. *pMaterial must be nullptr.
297 void Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNodeElement, aiMaterial** pMaterial) const;
298
299 /// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract
300 /// all needed data from scene graph.
301 /// \param [in] pNodeElement - reference to geometry object.
302 /// \param [out] pMesh - pointer to pointer to created mesh. *pMesh must be nullptr.
303 void Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeElement, aiMesh** pMesh) const;
304
305 /// Create aiNode from CX3DImporter_NodeElement. Also function check children and make recursive call.
306 /// \param [out] pNode - pointer to pointer to created node. *pNode must be nullptr.
307 /// \param [in] pNodeElement - CX3DImporter_NodeElement which read.
308 /// \param [out] pSceneNode - aiNode for filling.
309 /// \param [out] pSceneMeshList - list with aiMesh which belong to scene.
310 /// \param [out] pSceneMaterialList - list with aiMaterial which belong to scene.
311 /// \param [out] pSceneLightList - list with aiLight which belong to scene.
312 void Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list<aiMesh*>& pSceneMeshList,
313 std::list<aiMaterial*>& pSceneMaterialList, std::list<aiLight*>& pSceneLightList) const;
314
315 /// To create mesh and material kept in <Schape>.
316 /// \param pShapeNodeElement - reference to node element which kept <Shape> data.
317 /// \param pNodeMeshInd - reference to list with mesh indices. When pShapeNodeElement will read new mesh index will be added to this list.
318 /// \param pSceneMeshList - reference to list with meshes. When pShapeNodeElement will read new mesh will be added to this list.
319 /// \param pSceneMaterialList - reference to list with materials. When pShapeNodeElement will read new material will be added to this list.
320 void Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& pShapeNodeElement, std::list<unsigned int>& pNodeMeshInd,
321 std::list<aiMesh*>& pSceneMeshList, std::list<aiMaterial*>& pSceneMaterialList) const;
322
323 /// Check if child elements of node element is metadata and add it to scene node.
324 /// \param [in] pNodeElement - node element where metadata is searching.
325 /// \param [out] pSceneNode - scene node in which metadata will be added.
326 void Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode) const;
327
328 /***********************************************/
329 /************* Functions: throw set ************/
330 /***********************************************/
331
332 /// Call that function when argument is out of range and exception must be raised.
333 /// \throw DeadlyImportError.
334 /// \param [in] pArgument - argument name.
335 void Throw_ArgOutOfRange(const std::string& pArgument);
336
337 /// Call that function when close tag of node not found and exception must be raised.
338 /// E.g.:
339 /// <Scene>
340 /// <Shape>
341 /// </Scene> <!--- shape not closed --->
342 /// \throw DeadlyImportError.
343 /// \param [in] pNode - node name in which exception happened.
344 void Throw_CloseNotFound(const std::string& pNode);
345
346 /// Call that function when string value can not be converted to floating point value and exception must be raised.
347 /// \param [in] pAttrValue - attribute value.
348 /// \throw DeadlyImportError.
349 void Throw_ConvertFail_Str2ArrF(const std::string& pAttrValue);
350
351 /// Call that function when in node defined attributes "DEF" and "USE" and exception must be raised.
352 /// E.g.: <Box DEF="BigBox" USE="MegaBox">
353 /// \throw DeadlyImportError.
354 void Throw_DEF_And_USE();
355
356 /// Call that function when attribute name is incorrect and exception must be raised.
357 /// \param [in] pAttrName - attribute name.
358 /// \throw DeadlyImportError.
359 void Throw_IncorrectAttr(const std::string& pAttrName);
360
361 /// Call that function when attribute value is incorrect and exception must be raised.
362 /// \param [in] pAttrName - attribute name.
363 /// \throw DeadlyImportError.
364 void Throw_IncorrectAttrValue(const std::string& pAttrName);
365
366 /// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
367 /// E.g.:
368 /// <Shape>
369 /// <Box/> <!--- first geometry node --->
370 /// <Sphere/> <!--- second geometry node. raise exception --->
371 /// </Shape>
372 /// \throw DeadlyImportError.
373 /// \param [in] pNodeType - type of node which defined one more time.
374 /// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
375 void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
376
377 /// Call that function when count of opening and closing tags which create group(e.g. <Group>) are not equal and exception must be raised.
378 /// E.g.:
379 /// <Scene>
380 /// <Transform> <!--- first grouping node begin --->
381 /// <Group> <!--- second grouping node begin --->
382 /// </Transform> <!--- first grouping node end --->
383 /// </Scene> <!--- one grouping node still not closed --->
384 /// \throw DeadlyImportError.
385 /// \param [in] pNode - node name in which exception happened.
386 void Throw_TagCountIncorrect(const std::string& pNode);
387
388 /// Call that function when defined in "USE" element are not found in graph and exception must be raised.
389 /// \param [in] pAttrValue - "USE" attribute value.
390 /// \throw DeadlyImportError.
391 void Throw_USE_NotFound(const std::string& pAttrValue);
392
393 /***********************************************/
394 /************** Functions: LOG set *************/
395 /***********************************************/
396
397 /// Short variant for calling \ref DefaultLogger::get()->info()
398 void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); }
399
400 /***********************************************/
401 /************** Functions: XML set *************/
402 /***********************************************/
403
404 /// Check if current node is empty: <node />. If not then exception will throwed.
405 void XML_CheckNode_MustBeEmpty();
406
407 /// Check if current node name is equal to pNodeName.
408 /// \param [in] pNodeName - name for checking.
409 /// return true if current node name is equal to pNodeName, else - false.
410 bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
411
412 /// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
413 /// \param [in] pParentNodeName - parent node name. Used for reporting.
414 void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
415
416 /// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
417 /// \param [in] pNodeName - requested node name.
418 /// return true - if node is found, else - false.
419 bool XML_SearchNode(const std::string& pNodeName);
420
421 /// Read attribute value.
422 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
423 /// \return read data.
424 bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
425
426 /// Read attribute value.
427 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
428 /// \return read data.
429 float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
430
431 /// Read attribute value.
432 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
433 /// \return read data.
434 int32_t XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx);
435
436 /// Read attribute value.
437 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
438 /// \param [out] pValue - read data.
439 void XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue);
440
441 /// Read attribute value.
442 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
443 /// \param [out] pValue - read data.
444 void XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue);
445
446 /// Read attribute value.
447 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
448 /// \param [out] pValue - read data.
449 void XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue);
450
451 /// Read attribute value.
452 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
453 /// \param [out] pValue - read data.
454 void XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector<bool>& pValue);
455
456 /// Read attribute value.
457 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
458 /// \param [out] pValue - read data.
459 void XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector<int32_t>& pValue);
460
461 /// Read attribute value.
462 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
463 /// \param [out] pValue - read data.
464 void XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector<float>& pValue);
465
466 /// Read attribute value.
467 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
468 /// \param [out] pValue - read data.
469 void XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector<double>& pValue);
470
471 /// Read attribute value.
472 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
473 /// \param [out] pValue - read data.
474 void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list<aiColor3D>& pValue);
475
476 /// \overload void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::vector<aiColor3D>& pValue)
477 void XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::vector<aiColor3D>& pValue);
478
479 /// Read attribute value.
480 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
481 /// \param [out] pValue - read data.
482 void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list<aiColor4D>& pValue);
483
484 /// \overload void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list<aiColor4D>& pValue)
485 void XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::vector<aiColor4D>& pValue);
486
487 /// Read attribute value.
488 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
489 /// \param [out] pValue - read data.
490 void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list<aiVector2D>& pValue);
491
492 /// \overload void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list<aiVector2D>& pValue)
493 void XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::vector<aiVector2D>& pValue);
494
495 /// Read attribute value.
496 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
497 /// \param [out] pValue - read data.
498 void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list<aiVector3D>& pValue);
499
500 /// \overload void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list<aiVector3D>& pValue)
501 void XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::vector<aiVector3D>& pValue);
502
503 /// Read attribute value.
504 /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
505 /// \param [out] pValue - read data.
506 void XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list<std::string>& pValue);
507
508 /***********************************************/
509 /******* Functions: geometry helper set *******/
510 /***********************************************/
511
512 /// Make point on surface oXY.
513 /// \param [in] pAngle - angle in radians between radius-vector of point and oX axis. Angle extends from the oX axis counterclockwise to the radius-vector.
514 /// \param [in] pRadius - length of radius-vector.
515 /// \return made point coordinates.
516 aiVector3D GeometryHelper_Make_Point2D(const float pAngle, const float pRadius);
517
518 /// Make 2D figure - linear circular arc with center in (0, 0). The z-coordinate is 0. The arc extends from the pStartAngle counterclockwise
519 /// to the pEndAngle. If pStartAngle and pEndAngle have the same value, a circle is specified. If the absolute difference between pStartAngle
520 /// and pEndAngle is greater than or equal to 2pi, a circle is specified.
521 /// \param [in] pStartAngle - angle in radians of start of the arc.
522 /// \param [in] pEndAngle - angle in radians of end of the arc.
523 /// \param [in] pRadius - radius of the arc.
524 /// \param [out] pNumSegments - number of segments in arc. In other words - tesselation factor.
525 /// \param [out] pVertices - generated vertices.
526 void GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, std::list<aiVector3D>& pVertices);
527
528 /// Create line set from point set.
529 /// \param [in] pPoint - input points list.
530 /// \param [out] pLine - made lines list.
531 void GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>& pPoint, std::list<aiVector3D>& pLine);
532
533 /// Create CoordIdx of line set from CoordIdx of polyline set.
534 /// \param [in] pPolylineCoordIdx - vertices indices divided by delimiter "-1". Must contain faces with two or more indices.
535 /// \param [out] pLineCoordIdx - made CoordIdx of line set.
536 void GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list<int32_t>& pPolylineCoordIdx, std::list<int32_t>& pLineCoordIdx);
537
538 /// Make 3D body - rectangular parallelepiped with center in (0, 0). QL mean quadlist (\sa pVertices).
539 /// \param [in] pSize - scale factor for body for every axis. E.g. (1, 2, 1) mean: X-size and Z-size - 1, Y-size - 2.
540 /// \param [out] pVertices - generated vertices. The list of vertices is grouped in quads.
541 void GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSize, std::list<aiVector3D>& pVertices);
542
543 /// Create faces array from vertices indices array.
544 /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
545 /// \param [in] pFaces - created faces array.
546 /// \param [in] pPrimitiveTypes - type of primitives in faces.
547 void GeometryHelper_CoordIdxStr2FacesArr(const std::vector<int32_t>& pCoordIdx, std::vector<aiFace>& pFaces, unsigned int& pPrimitiveTypes) const;
548
549 /// Add colors to mesh.
550 /// a. If colorPerVertex is FALSE, colours are applied to each face, as follows:
551 /// If the colorIndex field is not empty, one colour is used for each face of the mesh. There shall be at least as many indices in the
552 /// colorIndex field as there are faces in the mesh. The colorIndex field shall not contain any negative entries.
553 /// If the colorIndex field is empty, the colours in the X3DColorNode node are applied to each face of the mesh in order.
554 /// There shall be at least as many colours in the X3DColorNode node as there are faces.
555 /// b. If colorPerVertex is TRUE, colours are applied to each vertex, as follows:
556 /// If the colorIndex field is not empty, colours are applied to each vertex of the mesh in exactly the same manner that the coordIndex
557 /// field is used to choose coordinates for each vertex from the <Coordinate> node. The colorIndex field shall contain end-of-face markers (-1)
558 /// in exactly the same places as the coordIndex field.
559 /// If the colorIndex field is empty, the coordIndex field is used to choose colours from the X3DColorNode node.
560 /// \param [in] pMesh - mesh for adding data.
561 /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
562 /// \param [in] pColorIdx - color indices for every vertex divided by delimiter "-1" if \ref pColorPerVertex is true. if \ref pColorPerVertex is false
563 /// then pColorIdx contain color indices for every faces and must not contain delimiter "-1".
564 /// \param [in] pColors - defined colors.
565 /// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face.
566 void MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
567 const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const;
568
569 /// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pColorIdx, const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const;
570 void MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
571 const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const;
572
573 /// Add colors to mesh.
574 /// \param [in] pMesh - mesh for adding data.
575 /// \param [in] pColors - defined colors.
576 /// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face.
577 void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const;
578
579 /// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const
580 void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const;
581
582 /// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor;
583 void MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pNormalIdx,
584 const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const;
585
586 /// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor;
587 void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const;
588
589 /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor;
590 void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pTexCoordIdx,
591 const std::list<aiVector2D>& pTexCoords) const;
592
593 /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor;
594 void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVector2D>& pTexCoords) const;
595
596 /// Create mesh.
597 /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
598 /// \param [in] pVertices - vertices of mesh.
599 /// \return created mesh.
600 aiMesh* GeometryHelper_MakeMesh(const std::vector<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const;
601
602 /***********************************************/
603 /******** Functions: parse set private *********/
604 /***********************************************/
605
606 /// Create node element with type "Node" in scene graph. That operation is needed when you enter to X3D group node
607 /// like <Group>, <Transform> etc. When exiting from X3D group node(e.g. </Group>) \ref ParseHelper_Node_Exit must
608 /// be called.
609 /// \param [in] pStatic - flag: if true then static node is created(e.g. <StaticGroup>).
610 void ParseHelper_Group_Begin(const bool pStatic = false);
611
612 /// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
613 /// \param [in] pNode - new current node.
614 void ParseHelper_Node_Enter(CX3DImporter_NodeElement* pNode);
615
616 /// This function must be called when exiting from X3D group node(e.g. </Group>). \ref ParseHelper_Group_Begin.
617 void ParseHelper_Node_Exit();
618
619 /// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
620 /// must be converted to right form - "0.xxx".
621 /// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
622 /// \param [out[ pOutString - output string with right form of values.
623 void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
624
625 /// Check if current node has nodes of type X3DMetadataObject. Why we must do it? Because X3DMetadataObject can be in any non-empty X3DNode.
626 /// Meaning that X3DMetadataObject can be in any non-empty node in <Scene>.
627 /// \return true - if metadata node are found and parsed, false - metadata not found.
628 bool ParseHelper_CheckRead_X3DMetadataObject();
629
630 /// Check if current node has nodes of type X3DGeometricPropertyNode. X3DGeometricPropertyNode
631 /// X3DGeometricPropertyNode inheritors:
632 /// <FogCoordinate>, <HAnimDisplacer>, <Color>, <ColorRGBA>, <Coordinate>, <CoordinateDouble>, <GeoCoordinate>, <Normal>,
633 /// <MultiTextureCoordinate>, <TextureCoordinate>, <TextureCoordinate3D>, <TextureCoordinate4D>, <TextureCoordinateGenerator>,
634 /// <FloatVertexAttribute>, <Matrix3VertexAttribute>, <Matrix4VertexAttribute>.
635 /// \return true - if nodes are found and parsed, false - nodes not found.
636 bool ParseHelper_CheckRead_X3DGeometricPropertyNode();
637
638 /// Parse <X3D> node of the file.
639 void ParseNode_Root();
640
641 /// Parse <head> node of the file.
642 void ParseNode_Head();
643
644 /// Parse <Scene> node of the file.
645 void ParseNode_Scene();
646
647 /// Parse child nodes of <Metadata*> node.
648 /// \param [in] pNodeName - parsed node name. Must be set because that function is general and name needed for checking the end
649 /// and error reporing.
650 /// \param [in] pParentElement - parent metadata element.
651 void ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& pNodeName);
652
653 /// Parse <MetadataBoolean> node of the file.
654 void ParseNode_MetadataBoolean();
655
656 /// Parse <MetadataDouble> node of the file.
657 void ParseNode_MetadataDouble();
658
659 /// Parse <MetadataFloat> node of the file.
660 void ParseNode_MetadataFloat();
661
662 /// Parse <MetadataInteger> node of the file.
663 void ParseNode_MetadataInteger();
664
665 /// Parse <MetadataSet> node of the file.
666 void ParseNode_MetadataSet();
667
668 /// \fn void ParseNode_MetadataString()
669 /// Parse <MetadataString> node of the file.
670 void ParseNode_MetadataString();
671
672 /// Parse <Arc2D> node of the file.
673 void ParseNode_Geometry2D_Arc2D();
674
675 /// Parse <ArcClose2D> node of the file.
676 void ParseNode_Geometry2D_ArcClose2D();
677
678 /// Parse <Circle2D> node of the file.
679 void ParseNode_Geometry2D_Circle2D();
680
681 /// Parse <Disk2D> node of the file.
682 void ParseNode_Geometry2D_Disk2D();
683
684 /// Parse <Polyline2D> node of the file.
685 void ParseNode_Geometry2D_Polyline2D();
686
687 /// Parse <Polypoint2D> node of the file.
688 void ParseNode_Geometry2D_Polypoint2D();
689
690 /// Parse <Rectangle2D> node of the file.
691 void ParseNode_Geometry2D_Rectangle2D();
692
693 /// Parse <TriangleSet2D> node of the file.
694 void ParseNode_Geometry2D_TriangleSet2D();
695
696 /// Parse <Box> node of the file.
697 void ParseNode_Geometry3D_Box();
698
699 /// Parse <Cone> node of the file.
700 void ParseNode_Geometry3D_Cone();
701
702 /// Parse <Cylinder> node of the file.
703 void ParseNode_Geometry3D_Cylinder();
704
705 /// Parse <ElevationGrid> node of the file.
706 void ParseNode_Geometry3D_ElevationGrid();
707
708 /// Parse <Extrusion> node of the file.
709 void ParseNode_Geometry3D_Extrusion();
710
711 /// Parse <IndexedFaceSet> node of the file.
712 void ParseNode_Geometry3D_IndexedFaceSet();
713
714 /// Parse <Sphere> node of the file.
715 void ParseNode_Geometry3D_Sphere();
716
717 /// Parse <Group> node of the file. And create new node in scene graph.
718 void ParseNode_Grouping_Group();
719
720 /// Doing actions at an exit from <Group>. Walk up in scene graph.
721 void ParseNode_Grouping_GroupEnd();
722
723 /// Parse <StaticGroup> node of the file. And create new node in scene graph.
724 void ParseNode_Grouping_StaticGroup();
725
726 /// Doing actions at an exit from <StaticGroup>. Walk up in scene graph.
727 void ParseNode_Grouping_StaticGroupEnd();
728
729 /// Parse <Switch> node of the file. And create new node in scene graph.
730 void ParseNode_Grouping_Switch();
731
732 /// Doing actions at an exit from <Switch>. Walk up in scene graph.
733 void ParseNode_Grouping_SwitchEnd();
734
735 /// Parse <Transform> node of the file. And create new node in scene graph.
736 void ParseNode_Grouping_Transform();
737
738 /// Doing actions at an exit from <Transform>. Walk up in scene graph.
739 void ParseNode_Grouping_TransformEnd();
740
741 /// Parse <Color> node of the file.
742 void ParseNode_Rendering_Color();
743
744 /// Parse <ColorRGBA> node of the file.
745 void ParseNode_Rendering_ColorRGBA();
746
747 /// Parse <Coordinate> node of the file.
748 void ParseNode_Rendering_Coordinate();
749
750 /// Parse <Normal> node of the file.
751 void ParseNode_Rendering_Normal();
752
753 /// Parse <IndexedLineSet> node of the file.
754 void ParseNode_Rendering_IndexedLineSet();
755
756 /// Parse <IndexedTriangleFanSet> node of the file.
757 void ParseNode_Rendering_IndexedTriangleFanSet();
758
759 /// Parse <IndexedTriangleSet> node of the file.
760 void ParseNode_Rendering_IndexedTriangleSet();
761
762 /// Parse <IndexedTriangleStripSet> node of the file.
763 void ParseNode_Rendering_IndexedTriangleStripSet();
764
765 /// Parse <LineSet> node of the file.
766 void ParseNode_Rendering_LineSet();
767
768 /// Parse <PointSet> node of the file.
769 void ParseNode_Rendering_PointSet();
770
771 /// Parse <TriangleFanSet> node of the file.
772 void ParseNode_Rendering_TriangleFanSet();
773
774 /// Parse <TriangleSet> node of the file.
775 void ParseNode_Rendering_TriangleSet();
776
777 /// Parse <TriangleStripSet> node of the file.
778 void ParseNode_Rendering_TriangleStripSet();
779
780 /// Parse <ImageTexture> node of the file.
781 void ParseNode_Texturing_ImageTexture();
782
783 /// Parse <TextureCoordinate> node of the file.
784 void ParseNode_Texturing_TextureCoordinate();
785
786 /// Parse <TextureTransform> node of the file.
787 void ParseNode_Texturing_TextureTransform();
788
789 /// Parse <Shape> node of the file.
790 void ParseNode_Shape_Shape();
791
792 /// Parse <Appearance> node of the file.
793 void ParseNode_Shape_Appearance();
794
795 /// Parse <Material> node of the file.
796 void ParseNode_Shape_Material();
797
798 /// Parse <Inline> node of the file.
799 void ParseNode_Networking_Inline();
800
801 /// Parse <DirectionalLight> node of the file.
802 void ParseNode_Lighting_DirectionalLight();
803
804 /// Parse <PointLight> node of the file.
805 void ParseNode_Lighting_PointLight();
806
807 /// Parse <SpotLight> node of the file.
808 void ParseNode_Lighting_SpotLight();
809
810private:
811 /***********************************************/
812 /******************** Types ********************/
813 /***********************************************/
814
815 /***********************************************/
816 /****************** Constants ******************/
817 /***********************************************/
818 static const aiImporterDesc Description;
819 //static const std::regex pattern_nws;
820 //static const std::regex pattern_true;
821
822
823 /***********************************************/
824 /****************** Variables ******************/
825 /***********************************************/
826 CX3DImporter_NodeElement* NodeElement_Cur;///< Current element.
827 std::unique_ptr<FIReader> mReader;///< Pointer to XML-reader object
828 IOSystem *mpIOHandler;
829};// class X3DImporter
830
831}// namespace Assimp
832
833#endif // INCLUDED_AI_X3D_IMPORTER_H
834