/// \file X3DImporter.hpp
/// \brief X3D-format files importer for Assimp.
/// \date 2015-2016
/// \author smal.root@gmail.com
// Thanks to acorn89 for support.
#ifndef INCLUDED_AI_X3D_IMPORTER_H
#define INCLUDED_AI_X3D_IMPORTER_H
#include "X3DImporter_Node.hpp"
// Header files, Assimp.
#include "assimp/DefaultLogger.hpp"
#include "assimp/importerdesc.h"
#include "assimp/ProgressHandler.hpp"
#include "assimp/types.h"
#include "BaseImporter.h"
#include "irrXMLWrapper.h"
namespace Assimp
{
/// \class X3DImporter
/// Class that holding scene graph which include: groups, geometry, metadata etc.
///
/// Limitations.
///
/// Pay attention that X3D is format for interactive graphic and simulations for web browsers.
/// So not all features can be imported using Assimp.
///
/// Unsupported nodes:
/// CAD geometry component:
/// "CADAssembly", "CADFace", "CADLayer", "CADPart", "IndexedQuadSet", "QuadSet"
/// Core component:
/// "ROUTE", "ExternProtoDeclare", "ProtoDeclare", "ProtoInstance", "ProtoInterface", "WorldInfo"
/// Distributed interactive simulation (DIS) component:
/// "DISEntityManager", "DISEntityTypeMapping", "EspduTransform", "ReceiverPdu", "SignalPdu", "TransmitterPdu"
/// Cube map environmental texturing component:
/// "ComposedCubeMapTexture", "GeneratedCubeMapTexture", "ImageCubeMapTexture"
/// Environmental effects component:
/// "Background", "Fog", "FogCoordinate", "LocalFog", "TextureBackground"
/// Environmental sensor component:
/// "ProximitySensor", "TransformSensor", "VisibilitySensor"
/// Followers component:
/// "ColorChaser", "ColorDamper", "CoordinateChaser", "CoordinateDamper", "OrientationChaser", "OrientationDamper", "PositionChaser",
/// "PositionChaser2D", "PositionDamper", "PositionDamper2D", "ScalarChaser", "ScalarDamper", "TexCoordChaser2D", "TexCoordDamper2D"
/// Geospatial component:
/// "GeoCoordinate", "GeoElevationGrid", "GeoLocation", "GeoLOD", "GeoMetadata", "GeoOrigin", "GeoPositionInterpolator", "GeoProximitySensor",
/// "GeoTouchSensor", "GeoTransform", "GeoViewpoint"
/// Humanoid Animation (H-Anim) component:
/// "HAnimDisplacer", "HAnimHumanoid", "HAnimJoint", "HAnimSegment", "HAnimSite"
/// Interpolation component:
/// "ColorInterpolator", "CoordinateInterpolator", "CoordinateInterpolator2D", "EaseInEaseOut", "NormalInterpolator", "OrientationInterpolator",
/// "PositionInterpolator", "PositionInterpolator2D", "ScalarInterpolator", "SplinePositionInterpolator", "SplinePositionInterpolator2D",
/// "SplineScalarInterpolator", "SquadOrientationInterpolator",
/// Key device sensor component:
/// "KeySensor", "StringSensor"
/// Layering component:
/// "Layer", "LayerSet", "Viewport"
/// Layout component:
/// "Layout", "LayoutGroup", "LayoutLayer", "ScreenFontStyle", "ScreenGroup"
/// Navigation component:
/// "Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup"
/// Networking component:
/// "Anchor", "LoadSensor"
/// NURBS component:
/// "Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface",
/// "NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate",
/// "NurbsTrimmedSurface"
/// Particle systems component:
/// "BoundedPhysicsModel", "ConeEmitter", "ExplosionEmitter", "ForcePhysicsModel", "ParticleSystem", "PointEmitter", "PolylineEmitter",
/// "SurfaceEmitter", "VolumeEmitter", "WindPhysicsModel"
/// Picking component:
/// "LinePickSensor", "PickableGroup", "PointPickSensor", "PrimitivePickSensor", "VolumePickSensor"
/// Pointing device sensor component:
/// "CylinderSensor", "PlaneSensor", "SphereSensor", "TouchSensor"
/// Rendering component:
/// "ClipPlane"
/// Rigid body physics:
/// "BallJoint", "CollidableOffset", "CollidableShape", "CollisionCollection", "CollisionSensor", "CollisionSpace", "Contact", "DoubleAxisHingeJoint",
/// "MotorJoint", "RigidBody", "RigidBodyCollection", "SingleAxisHingeJoint", "SliderJoint", "UniversalJoint"
/// Scripting component:
/// "Script"
/// Programmable shaders component:
/// "ComposedShader", "FloatVertexAttribute", "Matrix3VertexAttribute", "Matrix4VertexAttribute", "PackagedShader", "ProgramShader", "ShaderPart",
/// "ShaderProgram",
/// Shape component:
/// "FillProperties", "LineProperties", "TwoSidedMaterial"
/// Sound component:
/// "AudioClip", "Sound"
/// Text component:
/// "FontStyle", "Text"
/// Texturing3D Component:
/// "ComposedTexture3D", "ImageTexture3D", "PixelTexture3D", "TextureCoordinate3D", "TextureCoordinate4D", "TextureTransformMatrix3D",
/// "TextureTransform3D"
/// Texturing component:
/// "MovieTexture", "MultiTexture", "MultiTextureCoordinate", "MultiTextureTransform", "PixelTexture", "TextureCoordinateGenerator",
/// "TextureProperties",
/// Time component:
/// "TimeSensor"
/// Event Utilities component:
/// "BooleanFilter", "BooleanSequencer", "BooleanToggle", "BooleanTrigger", "IntegerSequencer", "IntegerTrigger", "TimeTrigger",
/// Volume rendering component:
/// "BlendedVolumeStyle", "BoundaryEnhancementVolumeStyle", "CartoonVolumeStyle", "ComposedVolumeStyle", "EdgeEnhancementVolumeStyle",
/// "IsoSurfaceVolumeData", "OpacityMapVolumeStyle", "ProjectionVolumeStyle", "SegmentedVolumeData", "ShadedVolumeStyle",
/// "SilhouetteEnhancementVolumeStyle", "ToneMappedVolumeStyle", "VolumeData"
///
/// Supported nodes:
/// Core component:
/// "MetadataBoolean", "MetadataDouble", "MetadataFloat", "MetadataInteger", "MetadataSet", "MetadataString"
/// Geometry2D component:
/// "Arc2D", "ArcClose2D", "Circle2D", "Disk2D", "Polyline2D", "Polypoint2D", "Rectangle2D", "TriangleSet2D"
/// Geometry3D component:
/// "Box", "Cone", "Cylinder", "ElevationGrid", "Extrusion", "IndexedFaceSet", "Sphere"
/// Grouping component:
/// "Group", "StaticGroup", "Switch", "Transform"
/// Lighting component:
/// "DirectionalLight", "PointLight", "SpotLight"
/// Networking component:
/// "Inline"
/// Rendering component:
/// "Color", "ColorRGBA", "Coordinate", "IndexedLineSet", "IndexedTriangleFanSet", "IndexedTriangleSet", "IndexedTriangleStripSet", "LineSet",
/// "PointSet", "TriangleFanSet", "TriangleSet", "TriangleStripSet", "Normal"
/// Shape component:
/// "Shape", "Appearance", "Material"
/// Texturing component:
/// "ImageTexture", "TextureCoordinate", "TextureTransform"
///
/// Limitations of attribute "USE".
/// If "USE" is set then node must be empty, like that:
///
/// not the
///
///
/// Ignored attributes: "creaseAngle", "convex", "solid".
///
/// Texture coordinates generating: only for Sphere, Cone, Cylinder. In all other case used PLANE mapping.
/// It's better that Assimp main code has powerfull texture coordinates generator. Then is not needed to
/// duplicate this code in every importer.
///
/// Lighting limitations.
/// If light source placed in some group with "DEF" set. And after that some node is use it group with "USE" attribute then
/// you will get error about duplicate light sources. That's happening because Assimp require names for lights but do not like
/// duplicates of it )).
///
/// Color for faces.
/// That's happening when attribute "colorPerVertex" is set to "false". But Assimp do not hold how many colors has mesh and require
/// equal length for mVertices and mColors. You will see the colors but vertices will use call which last used in "colorIdx".
///
/// That's all for now. Enjoy
///
class X3DImporter : public BaseImporter
{
/***********************************************/
/******************** Types ********************/
/***********************************************/
/***********************************************/
/****************** Constants ******************/
/***********************************************/
private:
static const aiImporterDesc Description;
/***********************************************/
/****************** Variables ******************/
/***********************************************/
private:
CX3DImporter_NodeElement* NodeElement_Cur;///< Current element.
irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
std::string mFileDir;
public:
std::list NodeElement_List;///< All elements of scene graph.
/***********************************************/
/****************** Functions ******************/
/***********************************************/
private:
/// \fn X3DImporter(const X3DImporter& pScene)
/// Disabled copy constructor.
X3DImporter(const X3DImporter& pScene);
/// \fn X3DImporter& operator=(const X3DImporter& pScene)
/// Disabled assign operator.
X3DImporter& operator=(const X3DImporter& pScene);
/// \fn void Clear()
/// Clear all temporary data.
void Clear();
/***********************************************/
/************* Functions: find set *************/
/***********************************************/
/// \fn bool FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
/// Find requested node element. Search will be made in all existing nodes.
/// \param [in] pID - ID of requested element.
/// \param [in] pType - type of requested element.
/// \param [out] pElement - pointer to pointer to item found.
/// \return true - if the element is found, else - false.
bool FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement);
/// \fn bool FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
/// Find requested node element. Search will be made from pointed node down to childs.
/// \param [in] pStartNode - pointer to start node.
/// \param [in] pID - ID of requested element.
/// \param [in] pType - type of requested element.
/// \param [out] pElement - pointer to pointer to item found.
/// \return true - if the element is found, else - false.
bool FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, const std::string& pID, const CX3DImporter_NodeElement::EType pType,
CX3DImporter_NodeElement** pElement);
/// \fn bool FindNodeElement(const std::string& pName, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
/// Find requested node element. For "Node"'s accounting flag "Static".
/// \param [in] pName - name of requested element.
/// \param [in] pType - type of requested element.
/// \param [out] pElement - pointer to pointer to item found.
/// \return true - if the element is found, else - false.
bool FindNodeElement(const std::string& pName, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement);
/***********************************************/
/********* Functions: postprocess set **********/
/***********************************************/
/// \fn aiMatrix4x4 PostprocessHelper_Matrix_GlobalToCurrent() const
/// \return transformation matrix from global coordinate system to local.
aiMatrix4x4 PostprocessHelper_Matrix_GlobalToCurrent() const;
/// \fn void PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list& pList) const
/// Check if child elements of node element is metadata and add it to temporary list.
/// \param [in] pNodeElement - node element where metadata is searching.
/// \param [out] pList - temporary list for collected metadata.
void PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list& pList) const;
/// \fn bool bool PostprocessHelper_ElementIsMetadata(const CX3DImporter_NodeElement::EType pType) const
/// Check if type of node element is metadata. E.g. , .
/// \param [in] pType - checked type.
/// \return true - if the type corresponds to the metadata.
bool PostprocessHelper_ElementIsMetadata(const CX3DImporter_NodeElement::EType pType) const;
/// \fn bool PostprocessHelper_ElementIsMesh(const CX3DImporter_NodeElement::EType pType) const
/// Check if type of node element is geometry object and can be used to build mesh. E.g. , .
/// \param [in] pType - checked type.
/// \return true - if the type corresponds to the mesh.
bool PostprocessHelper_ElementIsMesh(const CX3DImporter_NodeElement::EType pType) const;
/// \fn void Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeElement, std::list& pSceneLightList) const
/// Read CX3DImporter_NodeElement_Light, create aiLight and add it to list of the lights.
/// \param [in] pNodeElement - reference to lisght element(, , ).
/// \param [out] pSceneLightList - reference to list of the lights.
void Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeElement, std::list& pSceneLightList) const;
/// \fn void Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNodeElement, aiMaterial** pMaterial) const
/// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract
/// all needed data from scene graph.
/// \param [in] pNodeElement - reference to material element().
/// \param [out] pMaterial - pointer to pointer to created material. *pMaterial must be nullptr.
void Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNodeElement, aiMaterial** pMaterial) const;
/// \fn void Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeElement, aiMesh** pMesh) const
/// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract
/// all needed data from scene graph.
/// \param [in] pNodeElement - reference to geometry object.
/// \param [out] pMesh - pointer to pointer to created mesh. *pMesh must be nullptr.
void Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeElement, aiMesh** pMesh) const;
/// \fn void Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list& pSceneMeshList, std::list& pSceneMaterialList, std::list& pSceneLightList) const
/// Create aiNode from CX3DImporter_NodeElement. Also function check children and make recursive call.
/// \param [out] pNode - pointer to pointer to created node. *pNode must be nullptr.
/// \param [in] pNodeElement - CX3DImporter_NodeElement which read.
/// \param [out] pSceneNode - aiNode for filling.
/// \param [out] pSceneMeshList - list with aiMesh which belong to scene.
/// \param [out] pSceneMaterialList - list with aiMaterial which belong to scene.
/// \param [out] pSceneLightList - list with aiLight which belong to scene.
void Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list& pSceneMeshList,
std::list& pSceneMaterialList, std::list& pSceneLightList) const;
/// \fn void Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& pShapeNodeElement, std::list& pNodeMeshInd, std::list& pSceneMeshList, std::list& pSceneMaterialList) const
/// To create mesh and material kept in .
/// \param pShapeNodeElement - reference to node element which kept data.
/// \param pNodeMeshInd - reference to list with mesh indices. When pShapeNodeElement will read new mesh index will be added to this list.
/// \param pSceneMeshList - reference to list with meshes. When pShapeNodeElement will read new mesh will be added to this list.
/// \param pSceneMaterialList - reference to list with materials. When pShapeNodeElement will read new material will be added to this list.
void Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& pShapeNodeElement, std::list& pNodeMeshInd,
std::list& pSceneMeshList, std::list& pSceneMaterialList) const;
/// \fn void Postprocess_CollectMetadata(aiNode& pSceneNode, const CX3DImporter_NodeElement& pNodeElement) const
/// Check if child elements of node element is metadata and add it to scene node.
/// \param [in] pNodeElement - node element where metadata is searching.
/// \param [out] pSceneNode - scene node in which metadata will be added.
void Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode) const;
/***********************************************/
/************* Functions: throw set ************/
/***********************************************/
/// \fn void Throw_ArgOutOfRange(const std::string& pArgument)
/// Call that function when argument is out of range and exception must be raised.
/// \throw DeadlyImportError.
/// \param [in] pArgument - argument name.
void Throw_ArgOutOfRange(const std::string& pArgument);
/// \fn void Throw_CloseNotFound(const std::string& pNode)
/// Call that function when close tag of node not found and exception must be raised.
/// E.g.:
///
///
///
/// \throw DeadlyImportError.
/// \param [in] pNode - node name in which exception happened.
void Throw_CloseNotFound(const std::string& pNode);
/// \fn void Throw_ConvertFail_Str2ArrF(const std::string& pAttrValue)
/// Call that function when string value can not be converted to floating point value and exception must be raised.
/// \param [in] pAttrValue - attribute value.
/// \throw DeadlyImportError.
void Throw_ConvertFail_Str2ArrF(const std::string& pAttrValue);
/// \fn void Throw_DEF_And_USE()
/// Call that function when in node defined attributes "DEF" and "USE" and exception must be raised.
/// E.g.:
/// \throw DeadlyImportError.
void Throw_DEF_And_USE();
/// \fn void Throw_IncorrectAttr(const std::string& pAttrName)
/// Call that function when attribute name is incorrect and exception must be raised.
/// \param [in] pAttrName - attribute name.
/// \throw DeadlyImportError.
void Throw_IncorrectAttr(const std::string& pAttrName);
/// \fn void Throw_IncorrectAttrValue(const std::string& pAttrName)
/// Call that function when attribute value is incorrect and exception must be raised.
/// \param [in] pAttrName - attribute name.
/// \throw DeadlyImportError.
void Throw_IncorrectAttrValue(const std::string& pAttrName);
/// \fn void Throw_MoreThanOnceDefined(const std::string& pNode, const std::string& pDescription)
/// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
/// E.g.:
///
///
///
///
/// \throw DeadlyImportError.
/// \param [in] pNodeType - type of node which defined one more time.
/// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
/// \fn void Throw_TagCountIncorrect(const std::string& pNode)
/// Call that function when count of opening and closing tags which create group(e.g. ) are not equal and exception must be raised.
/// E.g.:
///
///
///
///
///
/// \throw DeadlyImportError.
/// \param [in] pNode - node name in which exception happened.
void Throw_TagCountIncorrect(const std::string& pNode);
/// \fn void Throw_USE_NotFound(const std::string& pAttrValue)
/// Call that function when defined in "USE" element are not found in graph and exception must be raised.
/// \param [in] pAttrValue - "USE" attribute value.
/// \throw DeadlyImportError.
void Throw_USE_NotFound(const std::string& pAttrValue);
/***********************************************/
/************** Functions: LOG set *************/
/***********************************************/
/// \fn void LogInfo(const std::string& pMessage)
/// Short variant for calling \ref DefaultLogger::get()->info()
void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); }
/***********************************************/
/************** Functions: XML set *************/
/***********************************************/
/// \fn void XML_CheckNode_MustBeEmpty()
/// Chek if current node is empty: . If not then exception will throwed.
void XML_CheckNode_MustBeEmpty();
/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
/// Chek if current node name is equal to pNodeName.
/// \param [in] pNodeName - name for checking.
/// return true if current node name is equal to pNodeName, else - false.
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
/// \fn void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
/// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
/// \param [in] pParentNodeName - parent node name. Used for reporting.
void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
/// \fn bool XML_SearchNode(const std::string& pNodeName)
/// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
/// \param [in] pNodeName - requested node name.
/// return true - if node is found, else - false.
bool XML_SearchNode(const std::string& pNodeName);
/// \fn bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \return read data.
bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
/// \fn float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \return read data.
float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
/// \fn int32_t XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \return read data.
int32_t XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx);
/// \fn void XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListB(const int pAttrIdx, std::list& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector& pValue)
/// \overload void XML_ReadNode_GetAttrVal_AsListBool(const int pAttrIdx, std::list& pValue)
void XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector& pValue)
/// \overload void XML_ReadNode_GetAttrVal_AsListI32(const int pAttrIdx, std::list& pValue)
void XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector& pValue)
/// \overload void XML_ReadNode_GetAttrVal_AsListF(const int pAttrIdx, std::list& pValue)
void XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector& pValue)
/// \overload void XML_ReadNode_GetAttrVal_AsListD(const int pAttrIdx, std::list& pValue)
void XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::vector& pValue)
/// \overload void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::vector& pValue)
void XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::vector& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::vector& pValue)
/// \overload void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list& pValue)
void XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::vector& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::vector& pValue)
/// \overload void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list& pValue)
void XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::vector& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::vector& pValue)
/// \overload void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list& pValue)
void XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::vector& pValue);
/// \fn void XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list& pValue)
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \param [out] pValue - read data.
void XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list& pValue);
/***********************************************/
/******* Functions: geometry helper set *******/
/***********************************************/
/// \fn aiVector3D GeometryHelper_Make_Point2D(const float pAngle, const float pRadius)
/// Make point on surface oXY.
/// \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.
/// \param [in] pRadius - length of radius-vector.
/// \return made point coordinates.
aiVector3D GeometryHelper_Make_Point2D(const float pAngle, const float pRadius);
/// \fn void GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, std::list& pVertices)
/// Make 2D figure - linear circular arc with center in (0, 0). The z-coordinate is 0. The arc extends from the pStartAngle counterclockwise
/// to the pEndAngle. If pStartAngle and pEndAngle have the same value, a circle is specified. If the absolute difference between pStartAngle
/// and pEndAngle is greater than or equal to 2pi, a circle is specified.
/// \param [in] pStartAngle - angle in radians of start of the arc.
/// \param [in] pEndAngle - angle in radians of end of the arc.
/// \param [in] pRadius - radius of the arc.
/// \param [out] pNumSegments - number of segments in arc. In other words - tesselation factor.
/// \param [out] pVertices - generated vertices.
void GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, std::list& pVertices);
/// \fn void GeometryHelper_Extend_PointToLine(const std::list& pPoint, std::list& pLine)
/// Create line set from point set.
/// \param [in] pPoint - input points list.
/// \param [out] pLine - made lines list.
void GeometryHelper_Extend_PointToLine(const std::list& pPoint, std::list& pLine);
/// \fn GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list& pPolylineCoordIdx, std::list& pLineCoordIdx)
/// Create CoordIdx of line set from CoordIdx of polyline set.
/// \param [in] pPolylineCoordIdx - vertices indices divided by delimiter "-1". Must contain faces with two or more indices.
/// \param [out] pLineCoordIdx - made CoordIdx of line set.
void GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list& pPolylineCoordIdx, std::list& pLineCoordIdx);
/// \fn void GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSize, std::list& pVertices)
/// Make 3D body - rectangular parallelepiped with center in (0, 0). QL mean quadlist (\sa pVertices).
/// \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.
/// \param [out] pVertices - generated vertices. The list of vertices is grouped in quads.
void GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSize, std::list& pVertices);
/// \fn void GeometryHelper_CoordIdxStr2FacesArr(const std::list& pCoordIdx, std::vector& pFaces, unsigned int& pPrimitiveTypes) const
/// Create faces array from vertices indices array.
/// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
/// \param [in] pFaces - created faces array.
/// \param [in] pPrimitiveTypes - type of primitives in faces.
void GeometryHelper_CoordIdxStr2FacesArr(const std::list& pCoordIdx, std::vector& pFaces, unsigned int& pPrimitiveTypes) const;
/// \fn void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColors, const bool pColorPerVertex) const
/// Add colors to mesh.
/// a. If colorPerVertex is FALSE, colours are applied to each face, as follows:
/// 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
/// colorIndex field as there are faces in the mesh. The colorIndex field shall not contain any negative entries.
/// If the colorIndex field is empty, the colours in the X3DColorNode node are applied to each face of the mesh in order.
/// There shall be at least as many colours in the X3DColorNode node as there are faces.
/// b. If colorPerVertex is TRUE, colours are applied to each vertex, as follows:
/// If the colorIndex field is not empty, colours are applied to each vertex of the mesh in exactly the same manner that the coordIndex
/// field is used to choose coordinates for each vertex from the node. The colorIndex field shall contain end-of-face markers (−1)
/// in exactly the same places as the coordIndex field.
/// If the colorIndex field is empty, the coordIndex field is used to choose colours from the X3DColorNode node.
/// \param [in] pMesh - mesh for adding data.
/// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
/// \param [in] pColorIdx - color indices for every vertex divided by delimiter "-1" if \ref pColorPerVertex is true. if \ref pColorPerVertex is false
/// then pColorIdx contain color indices for every faces and must not contain delimiter "-1".
/// \param [in] pColors - defined colors.
/// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face.
void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx,
const std::list& pColors, const bool pColorPerVertex) const;
/// \fn void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const;
/// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx, const std::list& pColors, const bool pColorPerVertex) const;
void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pColorIdx,
const std::list& pColors, const bool pColorPerVertex) const;
/// \fn void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const
/// Add colors to mesh.
/// \param [in] pMesh - mesh for adding data.
/// \param [in] pColors - defined colors.
/// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face.
void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const;
/// \fn void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const
/// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const
void MeshGeometry_AddColor(aiMesh& pMesh, const std::list& pColors, const bool pColorPerVertex) const;
/// \fn void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pNormalIdx, const std::list& pNormals, const bool pNormalPerVertex) const
/// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor;
void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pNormalIdx,
const std::list& pNormals, const bool pNormalPerVertex) const;
/// \fn void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pNormals, const bool pNormalPerVertex) const
/// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor;
void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list& pNormals, const bool pNormalPerVertex) const;
/// \fn void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pTexCoordIdx, const std::list& pTexCoords) const
/// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor;
void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pCoordIdx, const std::list& pTexCoordIdx,
const std::list& pTexCoords) const;
/// \fn void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pTexCoords) const
/// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor;
void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list& pTexCoords) const;
/// \fn aiMesh* GeometryHelper_MakeMesh(const std::list& pCoordIdx, const std::list& pVertices) const
/// Create mesh.
/// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
/// \param [in] pVertices - vertices of mesh.
/// \return created mesh.
aiMesh* GeometryHelper_MakeMesh(const std::list& pCoordIdx, const std::list& pVertices) const;
/***********************************************/
/******** Functions: parse set private *********/
/***********************************************/
/// \fn void ParseHelper_Group_Begin()
/// Create node element with type "Node" in scene graph. That operation is needed when you enter to X3D group node
/// like , etc. When exiting from X3D group node(e.g. ) \ref ParseHelper_Node_Exit must
/// be called.
/// \param [in] pStatic - flag: if true then static node is created(e.g. ).
void ParseHelper_Group_Begin(const bool pStatic = false);
/// \fn void ParseHelper_Node_Enter(CX3DImporter_NodeElement* pNode)
/// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
/// \param [in] pNode - new current node.
void ParseHelper_Node_Enter(CX3DImporter_NodeElement* pNode);
/// \fn void ParseHelper_Group_End()
/// This function must be called when exiting from X3D group node(e.g. ). \ref ParseHelper_Group_Begin.
void ParseHelper_Node_Exit();
/// \fn void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
/// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
/// must be converted to right form - "0.xxx".
/// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
/// \param [out[ pOutString - output string with right form of values.
void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
/// \fn bool ParseHelper_CheckRead_X3DMetadataObject()
/// Check if current node has nodes of type X3DMetadataObject. Why we must do it? Because X3DMetadataObject can be in any non-empty X3DNode.
/// Meaning that X3DMetadataObject can be in any non-empty node in .
/// \return true - if metadata node are found and parsed, false - metadata not found.
bool ParseHelper_CheckRead_X3DMetadataObject();
/// \fn bool ParseHelper_CheckRead_X3DMetadataObject()
/// Check if current node has nodes of type X3DGeometricPropertyNode. X3DGeometricPropertyNode
/// X3DGeometricPropertyNode inheritors:
/// , , , , , , , ,
/// , , , , ,
/// , , .
/// \return true - if nodes are found and parsed, false - nodes not found.
bool ParseHelper_CheckRead_X3DGeometricPropertyNode();
/// \fn void ParseNode_Root()
/// Parse node of the file.
void ParseNode_Root();
/// \fn void ParseNode_Head()
/// Parse node of the file.
void ParseNode_Head();
/// \fn void ParseNode_Root()
/// Parse node of the file.
void ParseNode_Scene();
/// \fn void ParseNode_Metadata(CX3DImporter_NodeElement* pParent, const std::string& pNodeName)
/// Parse child nodes of node.
/// \param [in] pNodeName - parsed node name. Must be set because that function is general and name needed for checking the end
/// and error reporing.
/// \param [in] pParentElement - parent metadata element.
void ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& pNodeName);
/// \fn void ParseNode_MetadataBoolean()
/// Parse node of the file.
void ParseNode_MetadataBoolean();
/// \fn void ParseNode_MetadataDouble()
/// Parse node of the file.
void ParseNode_MetadataDouble();
/// \fn void ParseNode_MetadataFloat()
/// Parse node of the file.
void ParseNode_MetadataFloat();
/// \fn void ParseNode_MetadataInteger()
/// Parse node of the file.
void ParseNode_MetadataInteger();
/// \fn void ParseNode_MetadataSet()
/// Parse node of the file.
void ParseNode_MetadataSet();
/// \fn void ParseNode_MetadataString()
/// Parse node of the file.
void ParseNode_MetadataString();
/// \fn void ParseNode_Geometry2D_Arc2D()
/// Parse node of the file.
void ParseNode_Geometry2D_Arc2D();
/// \fn void ParseNode_Geometry2D_ArcClose2D()
/// Parse node of the file.
void ParseNode_Geometry2D_ArcClose2D();
/// \fn void ParseNode_Geometry2D_Circle2D()
/// Parse node of the file.
void ParseNode_Geometry2D_Circle2D();
/// \fn void ParseNode_Geometry2D_Disk2D()
/// Parse node of the file.
void ParseNode_Geometry2D_Disk2D();
/// \fn void ParseNode_Geometry2D_Polyline2D()
/// Parse node of the file.
void ParseNode_Geometry2D_Polyline2D();
/// \fn void ParseNode_Geometry2D_Polypoint2D()
/// Parse node of the file.
void ParseNode_Geometry2D_Polypoint2D();
/// \fn void ParseNode_Geometry2D_Rectangle2D()
/// Parse node of the file.
void ParseNode_Geometry2D_Rectangle2D();
/// \fn void ParseNode_Geometry2D_TriangleSet2D()
/// Parse node of the file.
void ParseNode_Geometry2D_TriangleSet2D();
/// \fn void ParseNode_Geometry3D_Box()
/// Parse node of the file.
void ParseNode_Geometry3D_Box();
/// \fn void ParseNode_Geometry3D_Cone()
/// Parse node of the file.
void ParseNode_Geometry3D_Cone();
/// \fn void ParseNode_Geometry3D_Cylinder()
/// Parse node of the file.
void ParseNode_Geometry3D_Cylinder();
/// \fn void ParseNode_Geometry3D_ElevationGrid()
/// Parse node of the file.
void ParseNode_Geometry3D_ElevationGrid();
/// \fn void ParseNode_Geometry3D_Extrusion()
/// Parse node of the file.
void ParseNode_Geometry3D_Extrusion();
/// \fn void ParseNode_Geometry3D_IndexedFaceSet()
/// Parse node of the file.
void ParseNode_Geometry3D_IndexedFaceSet();
/// \fn void ParseNode_Geometry3D_Sphere()
/// Parse node of the file.
void ParseNode_Geometry3D_Sphere();
/// \fn void ParseNode_Grouping_Group()
/// Parse node of the file. And create new node in scene graph.
void ParseNode_Grouping_Group();
/// \fn void ParseNode_Grouping_GroupEnd()
/// Doing actions at an exit from . Walk up in scene graph.
void ParseNode_Grouping_GroupEnd();
/// \fn void ParseNode_Grouping_StaticGroup()
/// Parse node of the file. And create new node in scene graph.
void ParseNode_Grouping_StaticGroup();
/// \fn void ParseNode_Grouping_StaticGroupEnd()
/// Doing actions at an exit from . Walk up in scene graph.
void ParseNode_Grouping_StaticGroupEnd();
/// \fn void ParseNode_Grouping_Switch()
/// Parse node of the file. And create new node in scene graph.
void ParseNode_Grouping_Switch();
/// \fn void ParseNode_Grouping_SwitchEnd()
/// Doing actions at an exit from . Walk up in scene graph.
void ParseNode_Grouping_SwitchEnd();
/// \fn void ParseNode_Grouping_Transform()
/// Parse node of the file. And create new node in scene graph.
void ParseNode_Grouping_Transform();
/// \fn void ParseNode_Grouping_TransformEnd()
/// Doing actions at an exit from . Walk up in scene graph.
void ParseNode_Grouping_TransformEnd();
/// \fn void ParseNode_Rendering_Color()
/// Parse node of the file.
void ParseNode_Rendering_Color();
/// \fn void ParseNode_Rendering_ColorRGBA()
/// Parse node of the file.
void ParseNode_Rendering_ColorRGBA();
/// \fn void ParseNode_Rendering_Coordinate()
/// Parse node of the file.
void ParseNode_Rendering_Coordinate();
/// \fn void ParseNode_Rendering_Normal()
/// Parse node of the file.
void ParseNode_Rendering_Normal();
/// \fn void ParseNode_Rendering_IndexedLineSet()
/// Parse node of the file.
void ParseNode_Rendering_IndexedLineSet();
/// \fn void ParseNode_Rendering_IndexedTriangleFanSet()
/// Parse node of the file.
void ParseNode_Rendering_IndexedTriangleFanSet();
/// \fn void ParseNode_Rendering_IndexedTriangleSet()
/// Parse node of the file.
void ParseNode_Rendering_IndexedTriangleSet();
/// \fn void ParseNode_Rendering_IndexedTriangleStripSet()
/// Parse node of the file.
void ParseNode_Rendering_IndexedTriangleStripSet();
/// \fn void ParseNode_Rendering_LineSet()
/// Parse node of the file.
void ParseNode_Rendering_LineSet();
/// \fn void ParseNode_Rendering_PointSet()
/// Parse node of the file.
void ParseNode_Rendering_PointSet();
/// \fn void ParseNode_Rendering_TriangleFanSet()
/// Parse node of the file.
void ParseNode_Rendering_TriangleFanSet();
/// \fn void ParseNode_Rendering_TriangleSet()
/// Parse node of the file.
void ParseNode_Rendering_TriangleSet();
/// \fn void ParseNode_Rendering_TriangleStripSet()
/// Parse node of the file.
void ParseNode_Rendering_TriangleStripSet();
/// \fn void ParseNode_Texturing_ImageTexture()
/// Parse node of the file.
void ParseNode_Texturing_ImageTexture();
/// \fn void ParseNode_Texturing_TextureCoordinate()
/// Parse node of the file.
void ParseNode_Texturing_TextureCoordinate();
/// \fn void ParseNode_Texturing_TextureTransform()
/// Parse node of the file.
void ParseNode_Texturing_TextureTransform();
/// \fn void ParseNode_Shape_Shape()
/// Parse node of the file.
void ParseNode_Shape_Shape();
/// \fn void ParseNode_Shape_Appearance()
/// Parse node of the file.
void ParseNode_Shape_Appearance();
/// \fn void ParseNode_Shape_Material()
/// Parse node of the file.
void ParseNode_Shape_Material();
/// \fn void ParseNode_Networking_Inline()
/// Parse node of the file.
void ParseNode_Networking_Inline();
/// \fn void ParseNode_Lighting_DirectionalLight()
/// Parse node of the file.
void ParseNode_Lighting_DirectionalLight();
/// \fn void ParseNode_Lighting_PointLight()
/// Parse node of the file.
void ParseNode_Lighting_PointLight();
/// \fn void ParseNode_Lighting_SpotLight()
/// Parse node of the file.
void ParseNode_Lighting_SpotLight();
public:
/// \fn X3DImporter()
/// Default constructor.
X3DImporter()
: NodeElement_Cur(nullptr), mReader(nullptr)
{}
/// \fn ~X3DImporter()
/// Default destructor.
~X3DImporter();
/***********************************************/
/******** Functions: parse set, public *********/
/***********************************************/
/// \fn void ParseFile(const std::string& pFile, IOSystem* pIOHandler)
/// Parse X3D file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
/// Also exception can be throwed if trouble will found.
/// \param [in] pFile - name of file to be parsed.
/// \param [in] pIOHandler - pointer to IO helper object.
void ParseFile(const std::string& pFile, IOSystem* pIOHandler);
/***********************************************/
/********* Functions: BaseImporter set *********/
/***********************************************/
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const;
void GetExtensionList(std::set& pExtensionList);
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
const aiImporterDesc* GetInfo ()const;
};// class X3DImporter
}// namespace Assimp
#endif // INCLUDED_AI_X3D_IMPORTER_H