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