3MF: Export metadata.

pull/1842/head
Kim Kulling 2018-03-20 14:10:08 +01:00
parent 3bcef7ed8f
commit 317f3e2a59
5 changed files with 116 additions and 21 deletions

View File

@ -117,6 +117,7 @@ bool D3MFExporter::exportArchive( const char *file ) {
if ( nullptr == m_zipArchive ) { if ( nullptr == m_zipArchive ) {
return false; return false;
} }
ok |= exportContentTypes(); ok |= exportContentTypes();
ok |= export3DModel(); ok |= export3DModel();
ok |= exportRelations(); ok |= exportRelations();
@ -181,6 +182,8 @@ bool D3MFExporter::export3DModel() {
mModelOutput << "<" << XmlTag::resources << ">"; mModelOutput << "<" << XmlTag::resources << ">";
mModelOutput << std::endl; mModelOutput << std::endl;
writeMetaData();
writeBaseMaterials(); writeBaseMaterials();
writeObjects(); writeObjects();
@ -209,6 +212,29 @@ void D3MFExporter::writeHeader() {
mModelOutput << std::endl; mModelOutput << std::endl;
} }
void D3MFExporter::writeMetaData() {
if ( nullptr == mScene->mMetaData ) {
return;
}
const unsigned int numMetaEntries( mScene->mMetaData->mNumProperties );
if ( 0 == numMetaEntries ) {
return;
}
const aiString *key;
const aiMetadataEntry *entry(nullptr);
for ( size_t i = 0; i < numMetaEntries; ++i ) {
mScene->mMetaData->Get( i, key, entry );
std::string k( key->C_Str() );
aiString value;
mScene->mMetaData->Get( k, value );
mModelOutput << "<" << XmlTag::meta << " " << XmlTag::meta_name << "=\"" << key->C_Str() << "\">";
mModelOutput << value.C_Str();
mModelOutput << "</" << XmlTag::meta << ">" << std::endl;
}
}
void D3MFExporter::writeBaseMaterials() { void D3MFExporter::writeBaseMaterials() {
mModelOutput << "<basematerials id=\"1\">\n"; mModelOutput << "<basematerials id=\"1\">\n";
for ( size_t i = 0; i < mScene->mNumMaterials; ++i ) { for ( size_t i = 0; i < mScene->mNumMaterials; ++i ) {

View File

@ -76,6 +76,7 @@ public:
protected: protected:
void writeHeader(); void writeHeader();
void writeMetaData();
void writeBaseMaterials(); void writeBaseMaterials();
void writeObjects(); void writeObjects();
void writeMesh( aiMesh *mesh ); void writeMesh( aiMesh *mesh );

View File

@ -111,28 +111,31 @@ public:
scene->mRootNode->mName.Set( "3MF" ); scene->mRootNode->mName.Set( "3MF" );
} }
// import the metadata
if ( !mMetaData.empty() ) { if ( !mMetaData.empty() ) {
const size_t numMeta( mMetaData.size() ); const size_t numMeta( mMetaData.size() );
scene->mMetaData = aiMetadata::Alloc( numMeta ); scene->mMetaData = aiMetadata::Alloc( numMeta );
for ( size_t i = 0; i < numMeta; ++i ) { for ( size_t i = 0; i < numMeta; ++i ) {
aiString val( mMetaData[ i ].value ); aiString val( mMetaData[ i ].value );
scene->mMetaData->Add( mMetaData[ i ].name, val ); scene->mMetaData->Set( i, mMetaData[ i ].name, val );
} }
} }
// import the meshes
scene->mNumMeshes = static_cast<unsigned int>( mMeshes.size()); scene->mNumMeshes = static_cast<unsigned int>( mMeshes.size());
scene->mMeshes = new aiMesh*[scene->mNumMeshes](); scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
std::copy( mMeshes.begin(), mMeshes.end(), scene->mMeshes); std::copy( mMeshes.begin(), mMeshes.end(), scene->mMeshes);
// import the materials
scene->mNumMaterials = static_cast<unsigned int>( mMatArray.size() ); scene->mNumMaterials = static_cast<unsigned int>( mMatArray.size() );
if ( 0 != scene->mNumMaterials ) { if ( 0 != scene->mNumMaterials ) {
scene->mMaterials = new aiMaterial*[ scene->mNumMaterials ]; scene->mMaterials = new aiMaterial*[ scene->mNumMaterials ];
std::copy( mMatArray.begin(), mMatArray.end(), scene->mMaterials ); std::copy( mMatArray.begin(), mMatArray.end(), scene->mMaterials );
} }
// create the scenegraph
scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size()); scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren](); scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren); std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
} }

View File

@ -308,7 +308,8 @@ bool IsVerboseFormat(const aiScene* pScene) {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties) { aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
unsigned int pPreprocessing, const ExportProperties* pProperties) {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
// when they create scenes from scratch, users will likely create them not in verbose // when they create scenes from scratch, users will likely create them not in verbose

View File

@ -67,6 +67,7 @@ typedef enum aiMetadataType {
AI_DOUBLE = 4, AI_DOUBLE = 4,
AI_AISTRING = 5, AI_AISTRING = 5,
AI_AIVECTOR3D = 6, AI_AIVECTOR3D = 6,
AI_META_MAX = 7,
#ifndef SWIG #ifndef SWIG
FORCE_32BIT = INT_MAX FORCE_32BIT = INT_MAX
@ -130,42 +131,103 @@ struct aiMetadata {
*/ */
aiMetadata() aiMetadata()
: mNumProperties(0) : mNumProperties(0)
, mKeys(NULL) , mKeys(nullptr)
, mValues(NULL) { , mValues(nullptr) {
// empty // empty
} }
aiMetadata( const aiMetadata &rhs )
: mNumProperties( rhs.mNumProperties )
, mKeys( nullptr )
, mValues( nullptr ) {
mKeys = new aiString[ mNumProperties ];
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
mKeys[ i ] = rhs.mKeys[ i ];
}
mValues = new aiMetadataEntry[ mNumProperties ];
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
mValues[ i ].mType = rhs.mValues[ i ].mType;
switch ( rhs.mValues[ i ].mType ) {
case AI_BOOL:
mValues[ i ].mData = new bool( rhs.mValues[i].mData );
break;
case AI_INT32: {
int32_t v;
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( int32_t ) );
mValues[ i ].mData = new int32_t( v );
}
break;
case AI_UINT64: {
uint64_t v;
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( uint64_t ) );
mValues[ i ].mData = new uint64_t( v );
}
break;
case AI_FLOAT: {
float v;
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( float ) );
mValues[ i ].mData = new float( v );
}
break;
case AI_DOUBLE: {
double v;
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( double ) );
mValues[ i ].mData = new double( v );
}
break;
case AI_AISTRING: {
aiString v;
rhs.Get<aiString>( mKeys[ i ], v );
mValues[ i ].mData = new aiString( v );
}
break;
case AI_AIVECTOR3D: {
aiVector3D v;
rhs.Get<aiVector3D>( mKeys[ i ], v );
mValues[ i ].mData = new aiVector3D( v );
}
break;
#ifndef SWIG
case FORCE_32BIT:
#endif
default:
break;
}
}
}
/** /**
* @brief The destructor. * @brief The destructor.
*/ */
~aiMetadata() { ~aiMetadata() {
delete [] mKeys; delete [] mKeys;
mKeys = NULL; mKeys = nullptr;
if (mValues) { if (mValues) {
// Delete each metadata entry // Delete each metadata entry
for (unsigned i=0; i<mNumProperties; ++i) { for (unsigned i=0; i<mNumProperties; ++i) {
void* data = mValues[i].mData; void* data = mValues[i].mData;
switch (mValues[i].mType) { switch (mValues[i].mType) {
case AI_BOOL: case AI_BOOL:
delete static_cast<bool*>(data); delete static_cast< bool* >( data );
break; break;
case AI_INT32: case AI_INT32:
delete static_cast<int32_t*>(data); delete static_cast< int32_t* >( data );
break; break;
case AI_UINT64: case AI_UINT64:
delete static_cast<uint64_t*>(data); delete static_cast< uint64_t* >( data );
break; break;
case AI_FLOAT: case AI_FLOAT:
delete static_cast<float*>(data); delete static_cast< float* >( data );
break; break;
case AI_DOUBLE: case AI_DOUBLE:
delete static_cast<double*>(data); delete static_cast< double* >( data );
break; break;
case AI_AISTRING: case AI_AISTRING:
delete static_cast<aiString*>(data); delete static_cast< aiString* >( data );
break; break;
case AI_AIVECTOR3D: case AI_AIVECTOR3D:
delete static_cast<aiVector3D*>(data); delete static_cast< aiVector3D* >( data );
break; break;
#ifndef SWIG #ifndef SWIG
case FORCE_32BIT: case FORCE_32BIT:
@ -177,7 +239,7 @@ struct aiMetadata {
// Delete the metadata array // Delete the metadata array
delete [] mValues; delete [] mValues;
mValues = NULL; mValues = nullptr;
} }
} }
@ -208,8 +270,8 @@ struct aiMetadata {
} }
template<typename T> template<typename T>
inline void Add(const std::string& key, const T& value) inline
{ void Add(const std::string& key, const T& value) {
aiString* new_keys = new aiString[mNumProperties + 1]; aiString* new_keys = new aiString[mNumProperties + 1];
aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1]; aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1];
@ -256,7 +318,7 @@ struct aiMetadata {
template<typename T> template<typename T>
inline inline
bool Get( unsigned index, T& value ) { bool Get( unsigned index, T& value ) const {
// In range assertion // In range assertion
if ( index >= mNumProperties ) { if ( index >= mNumProperties ) {
return false; return false;
@ -277,7 +339,7 @@ struct aiMetadata {
template<typename T> template<typename T>
inline inline
bool Get( const aiString& key, T& value ) { bool Get( const aiString& key, T& value ) const {
// Search for the given key // Search for the given key
for ( unsigned int i = 0; i < mNumProperties; ++i ) { for ( unsigned int i = 0; i < mNumProperties; ++i ) {
if ( mKeys[ i ] == key ) { if ( mKeys[ i ] == key ) {
@ -288,7 +350,8 @@ struct aiMetadata {
} }
template<typename T> template<typename T>
inline bool Get( const std::string& key, T& value ) { inline
bool Get( const std::string& key, T& value ) const {
return Get(aiString(key), value); return Get(aiString(key), value);
} }
@ -297,7 +360,8 @@ struct aiMetadata {
/// \param [out] pKey - pointer to the key value. /// \param [out] pKey - pointer to the key value.
/// \param [out] pEntry - pointer to the entry: type and value. /// \param [out] pEntry - pointer to the entry: type and value.
/// \return false - if pIndex is out of range, else - true. /// \return false - if pIndex is out of range, else - true.
inline bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) { inline
bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) const {
if ( index >= mNumProperties ) { if ( index >= mNumProperties ) {
return false; return false;
} }