2016-10-06 14:04:37 +00:00
/// \file X3DExporter.hpp
/// \brief X3D-format files exporter for Assimp.
/// \date 2016
/// \author smal.root@gmail.com
// Thanks to acorn89 for support.
# ifndef INCLUDED_AI_X3D_EXPORTER_H
# define INCLUDED_AI_X3D_EXPORTER_H
// Header files, Assimp.
# include <assimp/material.h>
# include <assimp/scene.h>
2020-03-19 15:20:55 +00:00
# include <assimp/DefaultLogger.hpp>
# include <assimp/Exporter.hpp>
2016-10-06 14:04:37 +00:00
// Header files, stdlib.
# include <list>
# include <string>
2020-03-19 15:20:55 +00:00
namespace Assimp {
2016-10-06 14:04:37 +00:00
/// \class X3DExporter
/// Class which export aiScene to X3D file.
///
/// Limitations.
///
/// Pay attention that X3D is format for interactive graphic and simulations for web browsers. aiScene can not contain all features of the X3D format.
2018-05-13 14:35:03 +00:00
/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tessellation:
2017-11-09 22:19:26 +00:00
/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but that's not a good idea at all.
2016-10-06 14:04:37 +00:00
///
/// Supported nodes:
/// Core component:
/// "MetadataBoolean", "MetadataDouble", "MetadataFloat", "MetadataInteger", "MetadataSet", "MetadataString"
/// Geometry3D component:
/// "IndexedFaceSet"
/// Grouping component:
/// "Group", "Transform"
/// Lighting component:
/// "DirectionalLight", "PointLight", "SpotLight"
/// Rendering component:
2016-10-06 16:02:37 +00:00
/// "ColorRGBA", "Coordinate", "Normal"
2016-10-06 14:04:37 +00:00
/// Shape component:
/// "Shape", "Appearance", "Material"
/// Texturing component:
/// "ImageTexture", "TextureCoordinate", "TextureTransform"
///
2020-03-19 15:20:55 +00:00
class X3DExporter {
/***********************************************/
/******************** Types ********************/
/***********************************************/
struct SAttribute {
const std : : string Name ;
const std : : string Value ;
2020-03-19 14:25:34 +00:00
SAttribute ( ) :
2020-03-19 15:20:55 +00:00
Name ( ) ,
Value ( ) {
2020-03-19 14:25:34 +00:00
// empty
}
2020-03-20 12:18:49 +00:00
SAttribute ( const std : : string & name , const std : : string & value ) :
2020-03-19 15:20:55 +00:00
Name ( name ) ,
Value ( value ) {
// empty
}
2020-03-19 15:53:05 +00:00
2021-06-22 16:44:36 +00:00
SAttribute ( SAttribute & & rhs ) AI_NO_EXCEPT :
2021-06-22 16:27:15 +00:00
Name ( rhs . Name ) ,
Value ( rhs . Value ) {
2020-03-19 15:53:05 +00:00
// empty
}
2020-03-19 15:20:55 +00:00
} ;
2016-10-06 14:04:37 +00:00
2020-03-19 15:20:55 +00:00
/***********************************************/
/****************** Constants ******************/
/***********************************************/
2016-10-06 14:04:37 +00:00
2020-03-19 15:20:55 +00:00
const aiScene * const mScene ;
2016-10-06 14:04:37 +00:00
2020-03-19 15:20:55 +00:00
/***********************************************/
/****************** Variables ******************/
/***********************************************/
2016-10-06 14:04:37 +00:00
2020-03-19 15:20:55 +00:00
IOStream * mOutFile ;
std : : map < size_t , std : : string > mDEF_Map_Mesh ;
std : : map < size_t , std : : string > mDEF_Map_Material ;
2016-10-06 14:04:37 +00:00
private :
2020-03-19 15:20:55 +00:00
std : : string mIndentationString ;
/***********************************************/
/****************** Functions ******************/
/***********************************************/
/// \fn void IndentationStringSet(const size_t pNewLevel)
/// Set value of the indentation string.
/// \param [in] pNewLevel - new level of the indentation.
void IndentationStringSet ( const size_t pNewLevel ) ;
/// \fn void XML_Write(const std::string& pData)
/// Write data to XML-file.
/// \param [in] pData - reference to string which must be written.
void XML_Write ( const std : : string & pData ) ;
/// \fn aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const
/// Calculate transformation matrix for transformation from global coordinate system to pointed aiNode.
/// \param [in] pNode - reference to local node.
/// \return calculated matrix.
aiMatrix4x4 Matrix_GlobalToCurrent ( const aiNode & pNode ) const ;
/// \fn void AttrHelper_CommaToPoint(std::string& pStringWithComma)
/// Convert commas in string to points. That's needed because "std::to_string" result depends on locale (regional settings).
/// \param [in, out] pStringWithComma - reference to string, which must be modified.
void AttrHelper_CommaToPoint ( std : : string & pStringWithComma ) {
for ( char & c : pStringWithComma ) {
if ( c = = ' , ' ) c = ' . ' ;
}
}
/// \fn void AttrHelper_FloatToString(const float pValue, std::string& pTargetString)
/// Converts float to string.
/// \param [in] pValue - value for converting.
/// \param [out] pTargetString - reference to string where result will be placed. Will be cleared before using.
void AttrHelper_FloatToString ( const float pValue , std : : string & pTargetString ) ;
/// \fn void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
/// Converts array of vectors to string.
/// \param [in] pArray - pointer to array of vectors.
/// \param [in] pArray_Size - count of elements in array.
/// \param [out] pTargetString - reference to string where result will be placed. Will be cleared before using.
void AttrHelper_Vec3DArrToString ( const aiVector3D * pArray , const size_t pArray_Size , std : : string & pTargetString ) ;
/// \fn void AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString)
/// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
void AttrHelper_Vec2DArrToString ( const aiVector2D * pArray , const size_t pArray_Size , std : : string & pTargetString ) ;
/// \fn void AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
/// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
/// Only x, y is used from aiVector3D.
void AttrHelper_Vec3DAsVec2fArrToString ( const aiVector3D * pArray , const size_t pArray_Size , std : : string & pTargetString ) ;
/// \fn void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString)
/// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
/// Converts array of colors to string.
void AttrHelper_Col4DArrToString ( const aiColor4D * pArray , const size_t pArray_Size , std : : string & pTargetString ) ;
/// \fn void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
/// \overload void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString)
/// Converts array of colors to string.
void AttrHelper_Col3DArrToString ( const aiColor3D * pArray , const size_t pArray_Size , std : : string & pTargetString ) ;
/// \fn void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue)
/// \overload void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
void AttrHelper_FloatToAttrList ( std : : list < SAttribute > & pList , const std : : string & pName , const float pValue , const float pDefaultValue ) ;
/// \fn void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
/// Add attribute to list if value not equal to default.
/// \param [in] pList - target list of the attributes.
/// \param [in] pName - name of new attribute.
/// \param [in] pValue - value of the new attribute.
/// \param [in] pDefaultValue - default value for checking: if pValue is equal to pDefaultValue then attribute will not be added.
void AttrHelper_Color3ToAttrList ( std : : list < SAttribute > & pList , const std : : string & pName , const aiColor3D & pValue , const aiColor3D & pDefaultValue ) ;
/// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
/// Begin new XML-node element.
/// \param [in] pNodeName - name of the element.
/// \param [in] pTabLevel - indentation level.
/// \param [in] pEmtyElement - if true then empty element will be created.
/// \param [in] pAttrList - list of the attributes for element.
void NodeHelper_OpenNode ( const std : : string & pNodeName , const size_t pTabLevel , const bool pEmptyElement , const std : : list < SAttribute > & pAttrList ) ;
/// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement = false)
/// \overload void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
void NodeHelper_OpenNode ( const std : : string & pNodeName , const size_t pTabLevel , const bool pEmptyElement = false ) ;
/// \fn void NodeHelper_CloseNode(const std::string& pNodeName, const size_t pTabLevel)
/// End XML-node element.
/// \param [in] pNodeName - name of the element.
/// \param [in] pTabLevel - indentation level.
void NodeHelper_CloseNode ( const std : : string & pNodeName , const size_t pTabLevel ) ;
/// \fn void Export_Node(const aiNode* pNode, const size_t pTabLevel)
/// Export data from scene to XML-file: aiNode.
/// \param [in] pNode - source aiNode.
/// \param [in] pTabLevel - indentation level.
void Export_Node ( const aiNode * pNode , const size_t pTabLevel ) ;
/// \fn void Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel)
/// Export data from scene to XML-file: aiMesh.
/// \param [in] pMesh - index of the source aiMesh.
/// \param [in] pTabLevel - indentation level.
void Export_Mesh ( const size_t pIdxMesh , const size_t pTabLevel ) ;
/// \fn void Export_Material(const size_t pIdxMaterial, const size_t pTabLevel)
/// Export data from scene to XML-file: aiMaterial.
/// \param [in] pIdxMaterial - index of the source aiMaterial.
/// \param [in] pTabLevel - indentation level.
void Export_Material ( const size_t pIdxMaterial , const size_t pTabLevel ) ;
/// \fn void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
/// Export data from scene to XML-file: aiMetadata.
/// \param [in] pKey - source data: value of the metadata key.
/// \param [in] pValue - source data: value of the metadata value.
/// \param [in] pTabLevel - indentation level.
void Export_MetadataBoolean ( const aiString & pKey , const bool pValue , const size_t pTabLevel ) ;
/// \fn void Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel)
/// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
void Export_MetadataDouble ( const aiString & pKey , const double pValue , const size_t pTabLevel ) ;
/// \fn void Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel)
/// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
void Export_MetadataFloat ( const aiString & pKey , const float pValue , const size_t pTabLevel ) ;
/// \fn void Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel)
/// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
void Export_MetadataInteger ( const aiString & pKey , const int32_t pValue , const size_t pTabLevel ) ;
/// \fn void Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel)
/// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
void Export_MetadataString ( const aiString & pKey , const aiString & pValue , const size_t pTabLevel ) ;
/// \fn bool CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel)
/// Check if node point to light source. If yes then export light source.
/// \param [in] pNode - reference to node for checking.
/// \param [in] pTabLevel - indentation level.
/// \return true - if node assigned with light and it was exported, else - return false.
bool CheckAndExport_Light ( const aiNode & pNode , const size_t pTabLevel ) ;
/***********************************************/
/************** Functions: LOG set *************/
/***********************************************/
/// \fn void LogError(const std::string& pMessage)
/// Short variant for calling \ref DefaultLogger::get()->error()
void LogError ( const std : : string & pMessage ) { DefaultLogger : : get ( ) - > error ( pMessage ) ; }
2016-10-06 14:04:37 +00:00
public :
2020-03-19 15:20:55 +00:00
/// \fn X3DExporter()
/// Default constructor.
X3DExporter ( const char * pFileName , IOSystem * pIOSystem , const aiScene * pScene , const ExportProperties * pProperties ) ;
2016-10-06 14:04:37 +00:00
2020-03-19 15:20:55 +00:00
/// \fn ~X3DExporter()
/// Default destructor.
2022-09-01 16:28:45 +00:00
~ X3DExporter ( ) = default ;
2016-10-06 14:04:37 +00:00
2020-03-19 15:20:55 +00:00
} ; // class X3DExporter
2016-10-06 14:04:37 +00:00
2020-03-19 15:20:55 +00:00
} // namespace Assimp
2016-10-06 14:04:37 +00:00
# endif // INCLUDED_AI_X3D_EXPORTER_H