1/// \file X3DExporter.hpp
2/// \brief X3D-format files exporter for Assimp.
3/// \date 2016
4/// \author smal.root@gmail.com
5// Thanks to acorn89 for support.
6
7#ifndef INCLUDED_AI_X3D_EXPORTER_H
8#define INCLUDED_AI_X3D_EXPORTER_H
9
10// Header files, Assimp.
11#include <assimp/DefaultLogger.hpp>
12#include <assimp/Exporter.hpp>
13#include <assimp/material.h>
14#include <assimp/scene.h>
15
16// Header files, stdlib.
17#include <list>
18#include <string>
19
20namespace Assimp
21{
22
23/// \class X3DExporter
24/// Class which export aiScene to X3D file.
25///
26/// Limitations.
27///
28/// Pay attention that X3D is format for interactive graphic and simulations for web browsers. aiScene can not contain all features of the X3D format.
29/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tesselation:
30/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but that's not a good idea at all.
31///
32/// Supported nodes:
33/// Core component:
34/// "MetadataBoolean", "MetadataDouble", "MetadataFloat", "MetadataInteger", "MetadataSet", "MetadataString"
35/// Geometry3D component:
36/// "IndexedFaceSet"
37/// Grouping component:
38/// "Group", "Transform"
39/// Lighting component:
40/// "DirectionalLight", "PointLight", "SpotLight"
41/// Rendering component:
42/// "ColorRGBA", "Coordinate", "Normal"
43/// Shape component:
44/// "Shape", "Appearance", "Material"
45/// Texturing component:
46/// "ImageTexture", "TextureCoordinate", "TextureTransform"
47///
48class X3DExporter
49{
50 /***********************************************/
51 /******************** Types ********************/
52 /***********************************************/
53
54 struct SAttribute
55 {
56 const std::string Name;
57 const std::string Value;
58 };
59
60 /***********************************************/
61 /****************** Constants ******************/
62 /***********************************************/
63
64 const aiScene* const mScene;
65
66 /***********************************************/
67 /****************** Variables ******************/
68 /***********************************************/
69
70 IOStream* mOutFile;
71 std::map<size_t, std::string> mDEF_Map_Mesh;
72 std::map<size_t, std::string> mDEF_Map_Material;
73
74private:
75
76 std::string mIndentationString;
77
78 /***********************************************/
79 /****************** Functions ******************/
80 /***********************************************/
81
82 /// \fn void IndentationStringSet(const size_t pNewLevel)
83 /// Set value of the indentation string.
84 /// \param [in] pNewLevel - new level of the indentation.
85 void IndentationStringSet(const size_t pNewLevel);
86
87 /// \fn void XML_Write(const std::string& pData)
88 /// Write data to XML-file.
89 /// \param [in] pData - reference to string which must be written.
90 void XML_Write(const std::string& pData);
91
92 /// \fn aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const
93 /// Calculate transformation matrix for transformation from global coordinate system to pointed aiNode.
94 /// \param [in] pNode - reference to local node.
95 /// \return calculated matrix.
96 aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const;
97
98 /// \fn void AttrHelper_CommaToPoint(std::string& pStringWithComma)
99 /// Convert commas in string to points. That's needed because "std::to_string" result depends on locale (regional settings).
100 /// \param [in, out] pStringWithComma - reference to string, which must be modified.
101 void AttrHelper_CommaToPoint(std::string& pStringWithComma) { for(char& c: pStringWithComma) { if(c == ',') c = '.'; } }
102
103 /// \fn void AttrHelper_FloatToString(const float pValue, std::string& pTargetString)
104 /// Converts float to string.
105 /// \param [in] pValue - value for converting.
106 /// \param [out] pTargetString - reference to string where result will be placed. Will be cleared before using.
107 void AttrHelper_FloatToString(const float pValue, std::string& pTargetString);
108
109 /// \fn void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
110 /// Converts array of vectors to string.
111 /// \param [in] pArray - pointer to array of vectors.
112 /// \param [in] pArray_Size - count of elements in array.
113 /// \param [out] pTargetString - reference to string where result will be placed. Will be cleared before using.
114 void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString);
115
116 /// \fn void AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString)
117 /// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
118 void AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString);
119
120 /// \fn void AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
121 /// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
122 /// Only x, y is used from aiVector3D.
123 void AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString);
124
125 /// \fn void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString)
126 /// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
127 /// Converts array of colors to string.
128 void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString);
129
130 /// \fn void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
131 /// \overload void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString)
132 /// Converts array of colors to string.
133 void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString);
134
135 /// \fn void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue)
136 /// \overload void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
137 void AttrHelper_FloatToAttrList(std::list<SAttribute> &pList, const std::string& pName, const float pValue, const float pDefaultValue);
138
139 /// \fn void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
140 /// Add attribute to list if value not equal to default.
141 /// \param [in] pList - target list of the attributes.
142 /// \param [in] pName - name of new attribute.
143 /// \param [in] pValue - value of the new attribute.
144 /// \param [in] pDefaultValue - default value for checking: if pValue is equal to pDefaultValue then attribute will not be added.
145 void AttrHelper_Color3ToAttrList(std::list<SAttribute> &pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue);
146
147 /// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
148 /// Begin new XML-node element.
149 /// \param [in] pNodeName - name of the element.
150 /// \param [in] pTabLevel - indentation level.
151 /// \param [in] pEmtyElement - if true then empty element will be created.
152 /// \param [in] pAttrList - list of the attributes for element.
153 void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList);
154
155 /// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement = false)
156 /// \overload void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
157 void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement = false);
158
159 /// \fn void NodeHelper_CloseNode(const std::string& pNodeName, const size_t pTabLevel)
160 /// End XML-node element.
161 /// \param [in] pNodeName - name of the element.
162 /// \param [in] pTabLevel - indentation level.
163 void NodeHelper_CloseNode(const std::string& pNodeName, const size_t pTabLevel);
164
165 /// \fn void Export_Node(const aiNode* pNode, const size_t pTabLevel)
166 /// Export data from scene to XML-file: aiNode.
167 /// \param [in] pNode - source aiNode.
168 /// \param [in] pTabLevel - indentation level.
169 void Export_Node(const aiNode* pNode, const size_t pTabLevel);
170
171 /// \fn void Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel)
172 /// Export data from scene to XML-file: aiMesh.
173 /// \param [in] pMesh - index of the source aiMesh.
174 /// \param [in] pTabLevel - indentation level.
175 void Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel);
176
177 /// \fn void Export_Material(const size_t pIdxMaterial, const size_t pTabLevel)
178 /// Export data from scene to XML-file: aiMaterial.
179 /// \param [in] pIdxMaterial - index of the source aiMaterial.
180 /// \param [in] pTabLevel - indentation level.
181 void Export_Material(const size_t pIdxMaterial, const size_t pTabLevel);
182
183 /// \fn void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
184 /// Export data from scene to XML-file: aiMetadata.
185 /// \param [in] pKey - source data: value of the metadata key.
186 /// \param [in] pValue - source data: value of the metadata value.
187 /// \param [in] pTabLevel - indentation level.
188 void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel);
189
190 /// \fn void Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel)
191 /// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
192 void Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel);
193
194 /// \fn void Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel)
195 /// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
196 void Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel);
197
198 /// \fn void Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel)
199 /// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
200 void Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel);
201
202 /// \fn void Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel)
203 /// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
204 void Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel);
205
206 /// \fn bool CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel)
207 /// Check if node point to light source. If yes then export light source.
208 /// \param [in] pNode - reference to node for checking.
209 /// \param [in] pTabLevel - indentation level.
210 /// \return true - if node assigned with light and it was exported, else - return false.
211 bool CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel);
212
213 /***********************************************/
214 /************** Functions: LOG set *************/
215 /***********************************************/
216
217 /// \fn void LogError(const std::string& pMessage)
218 /// Short variant for calling \ref DefaultLogger::get()->error()
219 void LogError(const std::string& pMessage) { DefaultLogger::get()->error(pMessage); }
220
221public:
222
223 /// \fn X3DExporter()
224 /// Default constructor.
225 X3DExporter(const char* pFileName, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties);
226
227 /// \fn ~X3DExporter()
228 /// Default destructor.
229 ~X3DExporter() {}
230
231};// class X3DExporter
232
233}// namespace Assimp
234
235#endif // INCLUDED_AI_X3D_EXPORTER_H
236