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