diff options
Diffstat (limited to 'src/3rdparty/assimp/code')
175 files changed, 26048 insertions, 9115 deletions
diff --git a/src/3rdparty/assimp/code/3DSConverter.cpp b/src/3rdparty/assimp/code/3DSConverter.cpp index 07596ce9f..7bff38f3f 100644 --- a/src/3rdparty/assimp/code/3DSConverter.cpp +++ b/src/3rdparty/assimp/code/3DSConverter.cpp @@ -467,34 +467,41 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, const unsigned int iIndex = iArray[i]; aiMesh* const mesh = pcSOut->mMeshes[iIndex]; - // Transform the vertices back into their local space - // fixme: consider computing normals after this, so we don't need to transform them - const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices; - aiVector3D* pvCurrent = mesh->mVertices, *t2 = mesh->mNormals; - - for (;pvCurrent != pvEnd;++pvCurrent,++t2) { - *pvCurrent = mInv * (*pvCurrent); - *t2 = mInvTransposed * (*t2); - } - - // Handle negative transformation matrix determinant -> invert vertex x - if (imesh->mMat.Determinant() < 0.0f) + if (mesh->mColors[1] == NULL) { - /* we *must* have normals */ - for (pvCurrent = mesh->mVertices,t2 = mesh->mNormals;pvCurrent != pvEnd;++pvCurrent,++t2) { - pvCurrent->x *= -1.f; - t2->x *= -1.f; + // Transform the vertices back into their local space + // fixme: consider computing normals after this, so we don't need to transform them + const aiVector3D* const pvEnd = mesh->mVertices + mesh->mNumVertices; + aiVector3D* pvCurrent = mesh->mVertices, *t2 = mesh->mNormals; + + for (; pvCurrent != pvEnd; ++pvCurrent, ++t2) { + *pvCurrent = mInv * (*pvCurrent); + *t2 = mInvTransposed * (*t2); } - DefaultLogger::get()->info("3DS: Flipping mesh X-Axis"); - } - // Handle pivot point - if(pivot.x || pivot.y || pivot.z) - { - for (pvCurrent = mesh->mVertices;pvCurrent != pvEnd;++pvCurrent) { - *pvCurrent -= pivot; + // Handle negative transformation matrix determinant -> invert vertex x + if (imesh->mMat.Determinant() < 0.0f) + { + /* we *must* have normals */ + for (pvCurrent = mesh->mVertices, t2 = mesh->mNormals; pvCurrent != pvEnd; ++pvCurrent, ++t2) { + pvCurrent->x *= -1.f; + t2->x *= -1.f; + } + DefaultLogger::get()->info("3DS: Flipping mesh X-Axis"); + } + + // Handle pivot point + if (pivot.x || pivot.y || pivot.z) + { + for (pvCurrent = mesh->mVertices; pvCurrent != pvEnd; ++pvCurrent) { + *pvCurrent -= pivot; + } } + + mesh->mColors[1] = (aiColor4D*)1; } + else + mesh->mColors[1] = (aiColor4D*)1; // Setup the mesh index pcOut->mMeshes[i] = iIndex; @@ -502,7 +509,17 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, } // Setup the name of the node - pcOut->mName.Set(pcIn->mName); + // First instance keeps its name otherwise something might break, all others will be postfixed with their instance number + if (pcIn->mInstanceNumber > 1) + { + char tmp[12]; + ASSIMP_itoa10(tmp, pcIn->mInstanceNumber); + std::string tempStr = pcIn->mName + "_inst_"; + tempStr += tmp; + pcOut->mName.Set(tempStr); + } + else + pcOut->mName.Set(pcIn->mName); // Now build the transformation matrix of the node // ROTATION @@ -707,7 +724,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut) if (0 == mRootNode->mChildren.size()) { ////////////////////////////////////////////////////////////////////////////// - // It seems the file is so fucked up that it has not even a hierarchy. + // It seems the file is so messed up that it has not even a hierarchy. // generate a flat hiearachy which looks like this: // // ROOT_NODE @@ -784,9 +801,12 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut) AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m); } - // We used the first vertex color set to store some emporary values so we need to cleanup here - for (unsigned int a = 0; a < pcOut->mNumMeshes;++a) + // We used the first and second vertex color set to store some temporary values so we need to cleanup here + for (unsigned int a = 0; a < pcOut->mNumMeshes; ++a) + { pcOut->mMeshes[a]->mColors[0] = NULL; + pcOut->mMeshes[a]->mColors[1] = NULL; + } pcOut->mRootNode->mTransformation = aiMatrix4x4( 1.f,0.f,0.f,0.f, diff --git a/src/3rdparty/assimp/code/3DSHelper.h b/src/3rdparty/assimp/code/3DSHelper.h index dc95ec44d..8da7f0838 100644 --- a/src/3rdparty/assimp/code/3DSHelper.h +++ b/src/3rdparty/assimp/code/3DSHelper.h @@ -481,6 +481,7 @@ struct Node : mHierarchyPos (0) , mHierarchyIndex (0) + , mInstanceCount (1) { static int iCnt = 0; @@ -510,6 +511,9 @@ struct Node //! Name of the node std::string mName; + //! InstanceNumber of the node + int32_t mInstanceNumber; + //! Dummy nodes: real name to be combined with the $$$DUMMY std::string mDummyName; @@ -539,6 +543,9 @@ struct Node //! Pivot position loaded from the file aiVector3D vPivot; + //instance count, will be kept only for the first node + int32_t mInstanceCount; + //! Add a child node, setup the right parent node for it //! \param pc Node to be 'adopted' inline Node& push_back(Node* pc) diff --git a/src/3rdparty/assimp/code/3DSLoader.cpp b/src/3rdparty/assimp/code/3DSLoader.cpp index 377d15a34..137cceb1f 100644 --- a/src/3rdparty/assimp/code/3DSLoader.cpp +++ b/src/3rdparty/assimp/code/3DSLoader.cpp @@ -79,6 +79,8 @@ static const aiImporterDesc desc = { Discreet3DS::Chunk chunk; \ ReadChunk(&chunk); \ int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk); \ + if(chunkSize <= 0) \ + continue; \ const int oldReadLimit = stream->GetReadLimit(); \ stream->SetReadLimit(stream->GetCurrentPos() + chunkSize); \ @@ -657,14 +659,22 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) // Now find out whether we have this node already (target animation channels // are stored with a separate object ID) D3DS::Node* pcNode = FindNode(mRootNode,name); - if (pcNode) + int instanceNumber = 1; + + if ( pcNode) { - // Make this node the current node - mCurrentNode = pcNode; - break; + // if the source is not a CHUNK_TRACKINFO block it wont be an object instance + if (parent != Discreet3DS::CHUNK_TRACKINFO) + { + mCurrentNode = pcNode; + break; + } + pcNode->mInstanceCount++; + instanceNumber = pcNode->mInstanceCount; } pcNode = new D3DS::Node(); pcNode->mName = name; + pcNode->mInstanceNumber = instanceNumber; // There are two unknown values which we can safely ignore stream->IncPtr(4); diff --git a/src/3rdparty/assimp/code/3DSLoader.h b/src/3rdparty/assimp/code/3DSLoader.h index 9b3606f85..bee129cc1 100644 --- a/src/3rdparty/assimp/code/3DSLoader.h +++ b/src/3rdparty/assimp/code/3DSLoader.h @@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BaseImporter.h" #include "../include/assimp/types.h" +#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER + struct aiNode; #include "3DSHelper.h" @@ -271,6 +273,8 @@ protected: bool bIsPrj; }; +#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER + } // end of namespace Assimp #endif // AI_3DSIMPORTER_H_INC diff --git a/src/3rdparty/assimp/code/ASELoader.cpp b/src/3rdparty/assimp/code/ASELoader.cpp index 72c237349..9be97c87d 100644 --- a/src/3rdparty/assimp/code/ASELoader.cpp +++ b/src/3rdparty/assimp/code/ASELoader.cpp @@ -74,6 +74,7 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer ASEImporter::ASEImporter() +: noSkeletonMesh() {} // ------------------------------------------------------------------------------------------------ @@ -111,6 +112,8 @@ void ASEImporter::SetupProperties(const Importer* pImp) { configRecomputeNormals = (pImp->GetPropertyInteger( AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS,1) ? true : false); + + noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; } // ------------------------------------------------------------------------------------------------ @@ -244,7 +247,9 @@ void ASEImporter::InternReadFile( const std::string& pFile, // ------------------------------------------------------------------ if (!pScene->mNumMeshes) { pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; - SkeletonMeshBuilder skeleton(pScene); + if (!noSkeletonMesh) { + SkeletonMeshBuilder skeleton(pScene); + } } } // ------------------------------------------------------------------------------------------------ diff --git a/src/3rdparty/assimp/code/ASELoader.h b/src/3rdparty/assimp/code/ASELoader.h index b58a3fd10..903376a3c 100644 --- a/src/3rdparty/assimp/code/ASELoader.h +++ b/src/3rdparty/assimp/code/ASELoader.h @@ -197,6 +197,7 @@ protected: /** Config options: Recompute the normals in every case - WA for 3DS Max broken ASE normal export */ bool configRecomputeNormals; + bool noSkeletonMesh; }; } // end of namespace Assimp diff --git a/src/3rdparty/assimp/code/ASEParser.cpp b/src/3rdparty/assimp/code/ASEParser.cpp index 02d7c514e..df505a445 100644 --- a/src/3rdparty/assimp/code/ASEParser.cpp +++ b/src/3rdparty/assimp/code/ASEParser.cpp @@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AssimpPCH.h" +#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER // internal headers #include "TextureTransform.h" @@ -1566,8 +1567,8 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh) unsigned int iIndex = strtoul10(filePtr,&filePtr); if (iIndex >= iNumBones) { - continue; LogWarning("Bone index is out of bounds"); + continue; } if (!ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME")) SkipToNextToken(); @@ -2148,3 +2149,5 @@ void Parser::ParseLV4MeshLong(unsigned int& iOut) // parse the value iOut = strtoul10(filePtr,&filePtr); } + +#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER diff --git a/src/3rdparty/assimp/code/Assimp.cpp b/src/3rdparty/assimp/code/Assimp.cpp index 5c7389e38..e5e696098 100644 --- a/src/3rdparty/assimp/code/Assimp.cpp +++ b/src/3rdparty/assimp/code/Assimp.cpp @@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Importer.h" // ------------------------------------------------------------------------------------------------ -#ifdef AI_C_THREADSAFE +#ifndef ASSIMP_BUILD_SINGLETHREADED # include <boost/thread/thread.hpp> # include <boost/thread/mutex.hpp> #endif @@ -87,7 +87,7 @@ namespace Assimp } -#ifdef AI_C_THREADSAFE +#ifndef ASSIMP_BUILD_SINGLETHREADED /** Global mutex to manage the access to the logstream map */ static boost::mutex gLogStreamMutex; #endif @@ -104,7 +104,7 @@ public: } ~LogToCallbackRedirector() { -#ifdef AI_C_THREADSAFE +#ifndef ASSIMP_BUILD_SINGLETHREADED boost::mutex::scoped_lock lock(gLogStreamMutex); #endif // (HACK) Check whether the 'stream.user' pointer points to a @@ -172,6 +172,7 @@ const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFl pimpl->mIntProperties = pp->ints; pimpl->mFloatProperties = pp->floats; pimpl->mStringProperties = pp->strings; + pimpl->mMatrixProperties = pp->matrices; } // setup a custom IO system if necessary if (pFS) { @@ -230,6 +231,7 @@ const aiScene* aiImportFileFromMemoryWithProperties( pimpl->mIntProperties = pp->ints; pimpl->mFloatProperties = pp->floats; pimpl->mStringProperties = pp->strings; + pimpl->mMatrixProperties = pp->matrices; } // and have it read the file from the memory buffer @@ -337,7 +339,7 @@ ASSIMP_API void aiAttachLogStream( const aiLogStream* stream ) { ASSIMP_BEGIN_EXCEPTION_REGION(); -#ifdef AI_C_THREADSAFE +#ifndef ASSIMP_BUILD_SINGLETHREADED boost::mutex::scoped_lock lock(gLogStreamMutex); #endif @@ -356,7 +358,7 @@ ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream) { ASSIMP_BEGIN_EXCEPTION_REGION(); -#ifdef AI_C_THREADSAFE +#ifndef ASSIMP_BUILD_SINGLETHREADED boost::mutex::scoped_lock lock(gLogStreamMutex); #endif // find the logstream associated with this data @@ -381,7 +383,7 @@ ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream) ASSIMP_API void aiDetachAllLogStreams(void) { ASSIMP_BEGIN_EXCEPTION_REGION(); -#ifdef AI_C_THREADSAFE +#ifndef ASSIMP_BUILD_SINGLETHREADED boost::mutex::scoped_lock lock(gLogStreamMutex); #endif for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) { @@ -505,6 +507,20 @@ ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName } // ------------------------------------------------------------------------------------------------ +// Importer::SetPropertyMatrix +ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName, + const C_STRUCT aiMatrix4x4* mat) +{ + if (!mat) { + return; + } + ASSIMP_BEGIN_EXCEPTION_REGION(); + PropertyMap* pp = reinterpret_cast<PropertyMap*>(p); + SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat,NULL); + ASSIMP_END_EXCEPTION_REGION(void); +} + +// ------------------------------------------------------------------------------------------------ // Rotation matrix to quaternion ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat) { diff --git a/src/3rdparty/assimp/code/AssimpCExport.cpp b/src/3rdparty/assimp/code/AssimpCExport.cpp index 938127d96..1f806f133 100644 --- a/src/3rdparty/assimp/code/AssimpCExport.cpp +++ b/src/3rdparty/assimp/code/AssimpCExport.cpp @@ -64,6 +64,7 @@ ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex return Exporter().GetExportFormatDescription(pIndex); } + // ------------------------------------------------------------------------------------------------ ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut) { @@ -72,8 +73,19 @@ ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut) } SceneCombiner::CopyScene(pOut,pIn,true); + ScenePriv(*pOut)->mIsCopy = true; } + +// ------------------------------------------------------------------------------------------------ +ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn) +{ + // note: aiReleaseImport() is also able to delete scene copies, but in addition + // it also handles scenes with import metadata. + delete pIn; +} + + // ------------------------------------------------------------------------------------------------ ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing ) { diff --git a/src/3rdparty/assimp/code/AssimpPCH.cpp b/src/3rdparty/assimp/code/AssimpPCH.cpp index 0a1aa73c5..59e2620f8 100644 --- a/src/3rdparty/assimp/code/AssimpPCH.cpp +++ b/src/3rdparty/assimp/code/AssimpPCH.cpp @@ -4,6 +4,9 @@ #include "AssimpPCH.h" #include "./../include/assimp/version.h" +static const unsigned int MajorVersion = 3; +static const unsigned int MinorVersion = 1; + // -------------------------------------------------------------------------------- // Legal information string - dont't remove this. static const char* LEGAL_INFORMATION = @@ -25,13 +28,13 @@ ASSIMP_API const char* aiGetLegalString () { // ------------------------------------------------------------------------------------------------ // Get Assimp minor version ASSIMP_API unsigned int aiGetVersionMinor () { - return 0; + return MinorVersion; } // ------------------------------------------------------------------------------------------------ // Get Assimp major version ASSIMP_API unsigned int aiGetVersionMajor () { - return 3; + return MajorVersion; } // ------------------------------------------------------------------------------------------------ @@ -65,31 +68,31 @@ ASSIMP_API unsigned int aiGetCompileFlags () { // ------------------------------------------------------------------------------------------------ ASSIMP_API unsigned int aiGetVersionRevision () { - return SVNRevision; + return GitVersion; } // ------------------------------------------------------------------------------------------------ -aiScene::aiScene() - : mFlags() - , mRootNode() - , mNumMeshes() - , mMeshes() - , mNumMaterials() - , mMaterials() - , mNumAnimations() - , mAnimations() - , mNumTextures() - , mTextures() - , mNumLights() - , mLights() - , mNumCameras() - , mCameras() +ASSIMP_API aiScene::aiScene() + : mFlags(0) + , mRootNode(NULL) + , mNumMeshes(0) + , mMeshes(NULL) + , mNumMaterials(0) + , mMaterials(NULL) + , mNumAnimations(0) + , mAnimations(NULL) + , mNumTextures(0) + , mTextures(NULL) + , mNumLights(0) + , mLights(NULL) + , mNumCameras(0) + , mCameras(NULL) , mPrivate(new Assimp::ScenePrivateData()) { } // ------------------------------------------------------------------------------------------------ -aiScene::~aiScene() +ASSIMP_API aiScene::~aiScene() { // delete all sub-objects recursively delete mRootNode; diff --git a/src/3rdparty/assimp/code/AssimpPCH.h b/src/3rdparty/assimp/code/AssimpPCH.h index a431cfc9e..2c7a6bee4 100644 --- a/src/3rdparty/assimp/code/AssimpPCH.h +++ b/src/3rdparty/assimp/code/AssimpPCH.h @@ -74,7 +74,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* Helper macro to set a pointer to NULL in debug builds */ -#if (defined _DEBUG) +#if (defined ASSIMP_BUILD_DEBUG) # define AI_DEBUG_INVALIDATE_PTR(x) x = NULL; #else # define AI_DEBUG_INVALIDATE_PTR(x) diff --git a/src/3rdparty/assimp/code/BVHLoader.cpp b/src/3rdparty/assimp/code/BVHLoader.cpp index 1bbb43027..35a3e20ef 100644 --- a/src/3rdparty/assimp/code/BVHLoader.cpp +++ b/src/3rdparty/assimp/code/BVHLoader.cpp @@ -65,6 +65,7 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer BVHLoader::BVHLoader() +: noSkeletonMesh() {} // ------------------------------------------------------------------------------------------------ @@ -90,6 +91,12 @@ bool BVHLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs } // ------------------------------------------------------------------------------------------------ +void BVHLoader::SetupProperties(const Importer* pImp) +{ + noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; +} + +// ------------------------------------------------------------------------------------------------ // Loader meta information const aiImporterDesc* BVHLoader::GetInfo () const { @@ -119,8 +126,10 @@ void BVHLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSys mLine = 1; ReadStructure( pScene); - // build a dummy mesh for the skeleton so that we see something at least - SkeletonMeshBuilder meshBuilder( pScene); + if (!noSkeletonMesh) { + // build a dummy mesh for the skeleton so that we see something at least + SkeletonMeshBuilder meshBuilder( pScene); + } // construct an animation from all the motion data we read CreateAnimation( pScene); diff --git a/src/3rdparty/assimp/code/BVHLoader.h b/src/3rdparty/assimp/code/BVHLoader.h index ec7d33c57..279f6bf1e 100644 --- a/src/3rdparty/assimp/code/BVHLoader.h +++ b/src/3rdparty/assimp/code/BVHLoader.h @@ -94,6 +94,7 @@ public: * See BaseImporter::CanRead() for details. */ bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const; + void SetupProperties(const Importer* pImp); const aiImporterDesc* GetInfo () const; protected: @@ -159,6 +160,8 @@ protected: /** basic Animation parameters */ float mAnimTickDuration; unsigned int mAnimNumFrames; + + bool noSkeletonMesh; }; } // end of namespace Assimp diff --git a/src/3rdparty/assimp/code/BaseImporter.cpp b/src/3rdparty/assimp/code/BaseImporter.cpp index 88f3d9de8..4b7163dd5 100644 --- a/src/3rdparty/assimp/code/BaseImporter.cpp +++ b/src/3rdparty/assimp/code/BaseImporter.cpp @@ -380,6 +380,43 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data) } // ------------------------------------------------------------------------------------------------ +// Convert to UTF8 data to ISO-8859-1 +void BaseImporter::ConvertUTF8toISO8859_1(std::string& data) +{ + unsigned int size = data.size(); + unsigned int i = 0, j = 0; + + while(i < size) { + if((unsigned char) data[i] < 0x80) { + data[j] = data[i]; + } else if(i < size - 1) { + if((unsigned char) data[i] == 0xC2) { + data[j] = data[++i]; + } else if((unsigned char) data[i] == 0xC3) { + data[j] = ((unsigned char) data[++i] + 0x40); + } else { + std::stringstream stream; + + stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1."; + + DefaultLogger::get()->error(stream.str()); + + data[j++] = data[i++]; + data[j] = data[i]; + } + } else { + DefaultLogger::get()->error("UTF8 code but only one character remaining"); + + data[j] = data[i]; + } + + i++; j++; + } + + data.resize(j); +} + +// ------------------------------------------------------------------------------------------------ void BaseImporter::TextFileToBuffer(IOStream* stream, std::vector<char>& data) { @@ -533,7 +570,7 @@ void BatchLoader::LoadAll() for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) { // force validation in debug builds unsigned int pp = (*it).flags; -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG pp |= aiProcess_ValidateDataStructure; #endif // setup config properties if necessary @@ -541,6 +578,7 @@ void BatchLoader::LoadAll() pimpl->mFloatProperties = (*it).map.floats; pimpl->mIntProperties = (*it).map.ints; pimpl->mStringProperties = (*it).map.strings; + pimpl->mMatrixProperties = (*it).map.matrices; if (!DefaultLogger::isNullLogger()) { diff --git a/src/3rdparty/assimp/code/BaseImporter.h b/src/3rdparty/assimp/code/BaseImporter.h index a5fed5f15..491c9cea1 100644 --- a/src/3rdparty/assimp/code/BaseImporter.h +++ b/src/3rdparty/assimp/code/BaseImporter.h @@ -106,7 +106,7 @@ private: * imports the given file. ReadFile is not overridable, it just calls * InternReadFile() and catches any ImportErrorException that might occur. */ -class BaseImporter +class ASSIMP_API BaseImporter { friend class Importer; @@ -332,6 +332,15 @@ public: // static utilities std::vector<char>& data); // ------------------------------------------------------------------- + /** An utility for all text file loaders. It converts a file from our + * UTF8 character set back to ISO-8859-1. Errors are reported, but ignored. + * + * @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer + * is resized as appropriate. */ + static void ConvertUTF8toISO8859_1( + std::string& data); + + // ------------------------------------------------------------------- /** Utility for text file loaders which copies the contents of the * file into a memory buffer and converts it to our UTF8 * representation. diff --git a/src/3rdparty/assimp/code/Bitmap.cpp b/src/3rdparty/assimp/code/Bitmap.cpp new file mode 100644 index 000000000..30b5744ad --- /dev/null +++ b/src/3rdparty/assimp/code/Bitmap.cpp @@ -0,0 +1,145 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Bitmap.cpp + * @brief Defines bitmap format helper for textures + * + * Used for file formats which embed their textures into the model file. + */ + +#include "AssimpPCH.h" + +#include "Bitmap.h" + +namespace Assimp { + + void Bitmap::Save(aiTexture* texture, IOStream* file) { + if(file != NULL) { + Header header; + DIB dib; + + dib.size = DIB::dib_size; + dib.width = texture->mWidth; + dib.height = texture->mHeight; + dib.planes = 1; + dib.bits_per_pixel = 8 * mBytesPerPixel; + dib.compression = 0; + dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height; + dib.x_resolution = 0; + dib.y_resolution = 0; + dib.nb_colors = 0; + dib.nb_important_colors = 0; + + header.type = 0x4D42; // 'BM' + header.offset = Header::header_size + DIB::dib_size; + header.size = header.offset + dib.image_size; + header.reserved1 = 0; + header.reserved2 = 0; + + WriteHeader(header, file); + WriteDIB(dib, file); + WriteData(texture, file); + } + } + + template<typename T> + inline std::size_t Copy(uint8_t* data, T& field) { + std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field); + } + + void Bitmap::WriteHeader(Header& header, IOStream* file) { + uint8_t data[Header::header_size]; + + std::size_t offset = 0; + + offset += Copy(&data[offset], header.type); + offset += Copy(&data[offset], header.size); + offset += Copy(&data[offset], header.reserved1); + offset += Copy(&data[offset], header.reserved2); + offset += Copy(&data[offset], header.offset); + + file->Write(data, Header::header_size, 1); + } + + void Bitmap::WriteDIB(DIB& dib, IOStream* file) { + uint8_t data[DIB::dib_size]; + + std::size_t offset = 0; + + offset += Copy(&data[offset], dib.size); + offset += Copy(&data[offset], dib.width); + offset += Copy(&data[offset], dib.height); + offset += Copy(&data[offset], dib.planes); + offset += Copy(&data[offset], dib.bits_per_pixel); + offset += Copy(&data[offset], dib.compression); + offset += Copy(&data[offset], dib.image_size); + offset += Copy(&data[offset], dib.x_resolution); + offset += Copy(&data[offset], dib.y_resolution); + offset += Copy(&data[offset], dib.nb_colors); + offset += Copy(&data[offset], dib.nb_important_colors); + + file->Write(data, DIB::dib_size, 1); + } + + void Bitmap::WriteData(aiTexture* texture, IOStream* file) { + static const std::size_t padding_offset = 4; + static const uint8_t padding_data[padding_offset] = {0x0, 0x0, 0x0, 0x0}; + + unsigned int padding = (padding_offset - ((mBytesPerPixel * texture->mWidth) % padding_offset)) % padding_offset; + uint8_t pixel[mBytesPerPixel]; + + for(std::size_t i = 0; i < texture->mHeight; ++i) { + for(std::size_t j = 0; j < texture->mWidth; ++j) { + const aiTexel& texel = texture->pcData[(texture->mHeight - i - 1) * texture->mWidth + j]; // Bitmap files are stored in bottom-up format + + pixel[0] = texel.r; + pixel[1] = texel.g; + pixel[2] = texel.b; + pixel[3] = texel.a; + + file->Write(pixel, mBytesPerPixel, 1); + } + + file->Write(padding_data, padding, 1); + } + } + +} diff --git a/src/3rdparty/assimp/code/Bitmap.h b/src/3rdparty/assimp/code/Bitmap.h new file mode 100644 index 000000000..36f80363e --- /dev/null +++ b/src/3rdparty/assimp/code/Bitmap.h @@ -0,0 +1,139 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Bitmap.h + * @brief Defines bitmap format helper for textures + * + * Used for file formats which embed their textures into the model file. + */ + +#ifndef AI_BITMAP_H_INC +#define AI_BITMAP_H_INC + +namespace Assimp { + +class Bitmap { + + protected: + + struct Header { + + uint16_t type; + + uint32_t size; + + uint16_t reserved1; + + uint16_t reserved2; + + uint32_t offset; + + // We define the struct size because sizeof(Header) might return a wrong result because of structure padding. + // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). + static const std::size_t header_size = + sizeof(uint16_t) + // type + sizeof(uint32_t) + // size + sizeof(uint16_t) + // reserved1 + sizeof(uint16_t) + // reserved2 + sizeof(uint32_t); // offset + + }; + + struct DIB { + + uint32_t size; + + int32_t width; + + int32_t height; + + uint16_t planes; + + uint16_t bits_per_pixel; + + uint32_t compression; + + uint32_t image_size; + + int32_t x_resolution; + + int32_t y_resolution; + + uint32_t nb_colors; + + uint32_t nb_important_colors; + + // We define the struct size because sizeof(DIB) might return a wrong result because of structure padding. + // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). + static const std::size_t dib_size = + sizeof(uint32_t) + // size + sizeof(int32_t) + // width + sizeof(int32_t) + // height + sizeof(uint16_t) + // planes + sizeof(uint16_t) + // bits_per_pixel + sizeof(uint32_t) + // compression + sizeof(uint32_t) + // image_size + sizeof(int32_t) + // x_resolution + sizeof(int32_t) + // y_resolution + sizeof(uint32_t) + // nb_colors + sizeof(uint32_t); // nb_important_colors + + }; + + static const std::size_t mBytesPerPixel = 4; + + public: + + static void Save(aiTexture* texture, IOStream* file); + + protected: + + static void WriteHeader(Header& header, IOStream* file); + + static void WriteDIB(DIB& dib, IOStream* file); + + static void WriteData(aiTexture* texture, IOStream* file); + +}; + +} + +#endif // AI_BITMAP_H_INC diff --git a/src/3rdparty/assimp/code/BlenderBMesh.cpp b/src/3rdparty/assimp/code/BlenderBMesh.cpp new file mode 100644 index 000000000..0e517f4c8 --- /dev/null +++ b/src/3rdparty/assimp/code/BlenderBMesh.cpp @@ -0,0 +1,176 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2013, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file BlenderBMesh.cpp + * @brief Conversion of Blender's new BMesh stuff + */ + +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER + +#include "BlenderDNA.h" +#include "BlenderScene.h" +#include "BlenderBMesh.h" +#include "BlenderTessellator.h" + +namespace Assimp +{ + template< > const std::string LogFunctions< BlenderBMeshConverter >::log_prefix = "BLEND_BMESH: "; +} + +using namespace Assimp; +using namespace Assimp::Blender; +using namespace Assimp::Formatter; + +// ------------------------------------------------------------------------------------------------ +BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ): + BMesh( mesh ), + triMesh( NULL ) +{ + AssertValidMesh( ); +} + +// ------------------------------------------------------------------------------------------------ +BlenderBMeshConverter::~BlenderBMeshConverter( ) +{ + DestroyTriMesh( ); +} + +// ------------------------------------------------------------------------------------------------ +bool BlenderBMeshConverter::ContainsBMesh( ) const +{ + // TODO - Should probably do some additional verification here + return BMesh->totpoly && BMesh->totloop && BMesh->totvert; +} + +// ------------------------------------------------------------------------------------------------ +const Mesh* BlenderBMeshConverter::TriangulateBMesh( ) +{ + AssertValidMesh( ); + AssertValidSizes( ); + PrepareTriMesh( ); + + for ( int i = 0; i < BMesh->totpoly; ++i ) + { + const MPoly& poly = BMesh->mpoly[ i ]; + ConvertPolyToFaces( poly ); + } + + return triMesh; +} + +// ------------------------------------------------------------------------------------------------ +void BlenderBMeshConverter::AssertValidMesh( ) +{ + if ( !ContainsBMesh( ) ) + { + ThrowException( "BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first" ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderBMeshConverter::AssertValidSizes( ) +{ + if ( BMesh->totpoly != static_cast<int>( BMesh->mpoly.size( ) ) ) + { + ThrowException( "BMesh poly array has incorrect size" ); + } + if ( BMesh->totloop != static_cast<int>( BMesh->mloop.size( ) ) ) + { + ThrowException( "BMesh loop array has incorrect size" ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderBMeshConverter::PrepareTriMesh( ) +{ + if ( triMesh ) + { + DestroyTriMesh( ); + } + + triMesh = new Mesh( *BMesh ); + triMesh->totface = 0; + triMesh->mface.clear( ); +} + +// ------------------------------------------------------------------------------------------------ +void BlenderBMeshConverter::DestroyTriMesh( ) +{ + delete triMesh; + triMesh = NULL; +} + +// ------------------------------------------------------------------------------------------------ +void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly ) +{ + const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ]; + if ( poly.totloop == 3 || poly.totloop == 4 ) + { + AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 ); + } + else if ( poly.totloop > 4 ) + { +#if ASSIMP_BLEND_WITH_GLU_TESSELLATE + BlenderTessellatorGL tessGL( *this ); + tessGL.Tessellate( polyLoop, poly.totloop, triMesh->mvert ); +#elif ASSIMP_BLEND_WITH_POLY_2_TRI + BlenderTessellatorP2T tessP2T( *this ); + tessP2T.Tessellate( polyLoop, poly.totloop, triMesh->mvert ); +#endif + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 ) +{ + MFace face; + face.v1 = v1; + face.v2 = v2; + face.v3 = v3; + face.v4 = v4; + // TODO - Work out how materials work + face.mat_nr = 0; + triMesh->mface.push_back( face ); + triMesh->totface = triMesh->mface.size( ); +} + +#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER diff --git a/src/3rdparty/assimp/code/BlenderBMesh.h b/src/3rdparty/assimp/code/BlenderBMesh.h new file mode 100644 index 000000000..47afbf437 --- /dev/null +++ b/src/3rdparty/assimp/code/BlenderBMesh.h @@ -0,0 +1,93 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2013, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file BlenderBMesh.h + * @brief Conversion of Blender's new BMesh stuff + */ +#ifndef INCLUDED_AI_BLEND_BMESH_H +#define INCLUDED_AI_BLEND_BMESH_H + +#include "LogAux.h" + +namespace Assimp +{ + // TinyFormatter.h + namespace Formatter + { + template < typename T,typename TR, typename A > class basic_formatter; + typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format; + } + + // BlenderScene.h + namespace Blender + { + struct Mesh; + struct MPoly; + struct MLoop; + } + + class BlenderBMeshConverter: public LogFunctions< BlenderBMeshConverter > + { + public: + BlenderBMeshConverter( const Blender::Mesh* mesh ); + ~BlenderBMeshConverter( ); + + bool ContainsBMesh( ) const; + + const Blender::Mesh* TriangulateBMesh( ); + + private: + void AssertValidMesh( ); + void AssertValidSizes( ); + void PrepareTriMesh( ); + void DestroyTriMesh( ); + void ConvertPolyToFaces( const Blender::MPoly& poly ); + void AddFace( int v1, int v2, int v3, int v4 = 0 ); + + const Blender::Mesh* BMesh; + Blender::Mesh* triMesh; + + friend class BlenderTessellatorGL; + friend class BlenderTessellatorP2T; + }; + +} // end of namespace Assimp + +#endif // INCLUDED_AI_BLEND_BMESH_H diff --git a/src/3rdparty/assimp/code/BlenderDNA.h b/src/3rdparty/assimp/code/BlenderDNA.h index c5a875098..c52eb28a3 100644 --- a/src/3rdparty/assimp/code/BlenderDNA.h +++ b/src/3rdparty/assimp/code/BlenderDNA.h @@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "TinyFormatter.h" // enable verbose log output. really verbose, so be careful. -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG # define ASSIMP_BUILD_BLENDER_DEBUG #endif @@ -278,19 +278,23 @@ public: // -------------------------------------------------------- // field parsing for pointer or dynamic array types // (boost::shared_ptr or boost::shared_array) + // The return value indicates whether the data was already cached. template <int error_policy, template <typename> class TOUT, typename T> - void ReadFieldPtr(TOUT<T>& out, const char* name, - const FileDatabase& db) const; + bool ReadFieldPtr(TOUT<T>& out, const char* name, + const FileDatabase& db, + bool non_recursive = false) const; // -------------------------------------------------------- // field parsing for static arrays of pointer or dynamic // array types (boost::shared_ptr[] or boost::shared_array[]) + // The return value indicates whether the data was already cached. template <int error_policy, template <typename> class TOUT, typename T, size_t N> - void ReadFieldPtr(TOUT<T> (&out)[N], const char* name, + bool ReadFieldPtr(TOUT<T> (&out)[N], const char* name, const FileDatabase& db) const; // -------------------------------------------------------- // field parsing for `normal` values + // The return value indicates whether the data was already cached. template <int error_policy, typename T> void ReadField(T& out, const char* name, const FileDatabase& db) const; @@ -299,17 +303,18 @@ private: // -------------------------------------------------------- template <template <typename> class TOUT, typename T> - void ResolvePointer(TOUT<T>& out, const Pointer & ptrval, - const FileDatabase& db, const Field& f) const; + bool ResolvePointer(TOUT<T>& out, const Pointer & ptrval, + const FileDatabase& db, const Field& f, + bool non_recursive = false) const; // -------------------------------------------------------- template <template <typename> class TOUT, typename T> - void ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, - const FileDatabase& db, const Field& f) const; + bool ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, + const FileDatabase& db, const Field& f, bool) const; // -------------------------------------------------------- - void ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, - const FileDatabase& db, const Field& f) const; + bool ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, + const FileDatabase& db, const Field& f, bool) const; // -------------------------------------------------------- inline const FileBlockHead* LocateFileBlockForAddress( @@ -384,10 +389,11 @@ template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> { }; // ------------------------------------------------------------------------------------------------------- -template <> inline void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out, +template <> inline bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out, const Pointer & ptrval, const FileDatabase& db, - const Field& f + const Field& f, + bool ) const; diff --git a/src/3rdparty/assimp/code/BlenderDNA.inl b/src/3rdparty/assimp/code/BlenderDNA.inl index 818a8eac8..d555b7c85 100644 --- a/src/3rdparty/assimp/code/BlenderDNA.inl +++ b/src/3rdparty/assimp/code/BlenderDNA.inl @@ -180,7 +180,8 @@ void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileD //-------------------------------------------------------------------------------- template <int error_policy, template <typename> class TOUT, typename T> -void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db) const +bool Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db, + bool non_recursive /*= false*/) const { const StreamReaderAny::pos old = db.reader->GetCurrentPos(); Pointer ptrval; @@ -203,23 +204,27 @@ void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabas _defaultInitializer<error_policy>()(out,e.what()); out.reset(); - return; + return false; } // resolve the pointer and load the corresponding structure - ResolvePointer(out,ptrval,db,*f); + const bool res = ResolvePointer(out,ptrval,db,*f, non_recursive); - // and recover the previous stream position - db.reader->SetCurrentPos(old); + if(!non_recursive) { + // and recover the previous stream position + db.reader->SetCurrentPos(old); + } #ifndef ASSIMP_BUILD_BLENDER_NO_STATS ++db.stats().fields_read; #endif + + return res; } //-------------------------------------------------------------------------------- template <int error_policy, template <typename> class TOUT, typename T, size_t N> -void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name, +bool Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name, const FileDatabase& db) const { // XXX see if we can reduce this to call to the 'normal' ReadFieldPtr @@ -253,11 +258,13 @@ void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name, for(size_t i = 0; i < N; ++i) { out[i].reset(); } - return; + return false; } + + bool res = true; for(size_t i = 0; i < N; ++i) { // resolve the pointer and load the corresponding structure - ResolvePointer(out[i],ptrval[i],db,*f); + res = ResolvePointer(out[i],ptrval[i],db,*f) && res; } // and recover the previous stream position @@ -266,6 +273,7 @@ void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name, #ifndef ASSIMP_BUILD_BLENDER_NO_STATS ++db.stats().fields_read; #endif + return res; } //-------------------------------------------------------------------------------- @@ -296,11 +304,13 @@ void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) co //-------------------------------------------------------------------------------- template <template <typename> class TOUT, typename T> -void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const +bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db, + const Field& f, + bool non_recursive /*= false*/) const { - out.reset(); + out.reset(); // ensure null pointers work if (!ptrval.val) { - return; + return false; } const Structure& s = db.dna[f.type]; // find the file block the pointer is pointing to @@ -318,7 +328,7 @@ void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil // try to retrieve the object from the cache db.cache(out).get(s,out,ptrval); if (out) { - return; + return true; } // seek to this location, but save the previous stream pointer. @@ -334,27 +344,36 @@ void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil // cache the object before we convert it to avoid cyclic recursion. db.cache(out).set(s,out,ptrval); - for (size_t i = 0; i < num; ++i,++o) { - s.Convert(*o,db); - } + // if the non_recursive flag is set, we don't do anything but leave + // the cursor at the correct position to resolve the object. + if (!non_recursive) { + for (size_t i = 0; i < num; ++i,++o) { + s.Convert(*o,db); + } - db.reader->SetCurrentPos(pold); + db.reader->SetCurrentPos(pold); + } #ifndef ASSIMP_BUILD_BLENDER_NO_STATS if(out) { ++db.stats().pointers_resolved; } #endif + return false; } + //-------------------------------------------------------------------------------- -inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, const FileDatabase& db, const Field& /*f*/) const +inline bool Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, + const FileDatabase& db, + const Field&, + bool) const { // Currently used exclusively by PackedFile::data to represent // a simple offset into the mapped BLEND file. out.reset(); if (!ptrval.val) { - return; + return false; } // find the file block the pointer is pointing to @@ -362,11 +381,15 @@ inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, c out = boost::shared_ptr< FileOffset > (new FileOffset()); out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) ); + return false; } //-------------------------------------------------------------------------------- template <template <typename> class TOUT, typename T> -void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const +bool Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, + const FileDatabase& db, + const Field& f, + bool) const { // This is a function overload, not a template specialization. According to // the partial ordering rules, it should be selected by the compiler @@ -374,7 +397,7 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, out.reset(); if (!ptrval.val) { - return; + return false; } // find the file block the pointer is pointing to @@ -385,6 +408,7 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, const StreamReaderAny::pos pold = db.reader->GetCurrentPos(); db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) )); + bool res = false; // allocate raw storage for the array out.resize(num); for (size_t i = 0; i< num; ++i) { @@ -392,17 +416,19 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, Convert(val,db); // and resolve the pointees - ResolvePointer(out[i],val,db,f); + res = ResolvePointer(out[i],val,db,f) && res; } db.reader->SetCurrentPos(pold); + return res; } //-------------------------------------------------------------------------------- -template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out, +template <> bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out, const Pointer & ptrval, const FileDatabase& db, - const Field& /*f*/ + const Field&, + bool ) const { // Special case when the data type needs to be determined at runtime. @@ -410,7 +436,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost:: out.reset(); if (!ptrval.val) { - return; + return false; } // find the file block the pointer is pointing to @@ -422,7 +448,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost:: // try to retrieve the object from the cache db.cache(out).get(s,out,ptrval); if (out) { - return; + return true; } // seek to this location, but save the previous stream pointer. @@ -440,7 +466,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost:: DefaultLogger::get()->warn((Formatter::format(), "Failed to find a converter for the `",s.name,"` structure" )); - return; + return false; } // allocate the object hull @@ -459,11 +485,11 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost:: // to perform additional type checking. out->dna_type = s.name.c_str(); - #ifndef ASSIMP_BUILD_BLENDER_NO_STATS ++db.stats().pointers_resolved; #endif + return false; } //-------------------------------------------------------------------------------- diff --git a/src/3rdparty/assimp/code/BlenderLoader.cpp b/src/3rdparty/assimp/code/BlenderLoader.cpp index 2cbe89d81..8f9b85b26 100644 --- a/src/3rdparty/assimp/code/BlenderLoader.cpp +++ b/src/3rdparty/assimp/code/BlenderLoader.cpp @@ -1,3 +1,4 @@ + /* Open Asset Import Library (assimp) ---------------------------------------------------------------------- @@ -50,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BlenderIntermediate.h" #include "BlenderModifier.h" +#include "BlenderBMesh.h" #include "StreamReader.h" #include "MemoryIOWrapper.h" @@ -360,7 +362,7 @@ void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileD root->mNumChildren = static_cast<unsigned int>(no_parents.size()); root->mChildren = new aiNode*[root->mNumChildren](); for (unsigned int i = 0; i < root->mNumChildren; ++i) { - root->mChildren[i] = ConvertNode(in, no_parents[i], conv); + root->mChildren[i] = ConvertNode(in, no_parents[i], conv, aiMatrix4x4()); root->mChildren[i]->mParent = root; } @@ -445,9 +447,43 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M else { name = aiString( img->name ); } - out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE( - conv_data.next_texture[aiTextureType_DIFFUSE]++) - ); + + aiTextureType texture_type = aiTextureType_UNKNOWN; + MTex::MapType map_type = tex->mapto; + + if (map_type & MTex::MapType_COL) + texture_type = aiTextureType_DIFFUSE; + else if (map_type & MTex::MapType_NORM) { + if (tex->tex->imaflag & Tex::ImageFlags_NORMALMAP) { + texture_type = aiTextureType_NORMALS; + } + else { + texture_type = aiTextureType_HEIGHT; + } + out->AddProperty(&tex->norfac,1,AI_MATKEY_BUMPSCALING); + } + else if (map_type & MTex::MapType_COLSPEC) + texture_type = aiTextureType_SPECULAR; + else if (map_type & MTex::MapType_COLMIR) + texture_type = aiTextureType_REFLECTION; + //else if (map_type & MTex::MapType_REF) + else if (map_type & MTex::MapType_SPEC) + texture_type = aiTextureType_SHININESS; + else if (map_type & MTex::MapType_EMIT) + texture_type = aiTextureType_EMISSIVE; + //else if (map_type & MTex::MapType_ALPHA) + //else if (map_type & MTex::MapType_HAR) + //else if (map_type & MTex::MapType_RAYMIRR) + //else if (map_type & MTex::MapType_TRANSLU) + else if (map_type & MTex::MapType_AMB) + texture_type = aiTextureType_AMBIENT; + else if (map_type & MTex::MapType_DISPLACE) + texture_type = aiTextureType_DISPLACEMENT; + //else if (map_type & MTex::MapType_WARP) + + out->AddProperty(&name,AI_MATKEY_TEXTURE(texture_type, + conv_data.next_texture[texture_type]++)); + } // ------------------------------------------------------------------------------------------------ @@ -472,7 +508,7 @@ void BlenderImporter::ResolveTexture(aiMaterial* out, const Material* mat, const return; } - // We can't support most of the texture types because the're mostly procedural. + // We can't support most of the texture types because they're mostly procedural. // These are substituted by a dummy texture. const char* dispnam = ""; switch( rtex->type ) @@ -568,6 +604,11 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data) // Usually, zero diffuse color means no diffuse color at all in the equation. // So we omit this member to express this intent. mout->AddProperty(&col,1,AI_MATKEY_COLOR_DIFFUSE); + + if (mat->emit) { + aiColor3D emit_col(mat->emit * mat->r, mat->emit * mat->g, mat->emit * mat->b) ; + mout->AddProperty(&emit_col, 1, AI_MATKEY_COLOR_EMISSIVE) ; + } } col = aiColor3D(mat->specr,mat->specg,mat->specb); @@ -618,8 +659,14 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp ) { + BlenderBMeshConverter BMeshConverter( mesh ); + if ( BMeshConverter.ContainsBMesh( ) ) + { + mesh = BMeshConverter.TriangulateBMesh( ); + } + typedef std::pair<const int,size_t> MyPair; - if (!mesh->totface || !mesh->totvert) { + if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) { return; } @@ -632,12 +679,24 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co ThrowException("Number of vertices is larger than the corresponding array"); } + if (static_cast<size_t> ( mesh->totloop ) > mesh->mloop.size()) { + ThrowException("Number of vertices is larger than the corresponding array"); + } + // collect per-submesh numbers std::map<int,size_t> per_mat; + std::map<int,size_t> per_mat_verts; for (int i = 0; i < mesh->totface; ++i) { const MFace& mf = mesh->mface[i]; per_mat[ mf.mat_nr ]++; + per_mat_verts[ mf.mat_nr ] += mf.v4?4:3; + } + + for (int i = 0; i < mesh->totpoly; ++i) { + const MPoly& mp = mesh->mpoly[i]; + per_mat[ mp.mat_nr ]++; + per_mat_verts[ mp.mat_nr ] += mp.totloop; } // ... and allocate the corresponding meshes @@ -651,8 +710,8 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co temp->push_back(new aiMesh()); aiMesh* out = temp->back(); - out->mVertices = new aiVector3D[it.second*4]; - out->mNormals = new aiVector3D[it.second*4]; + out->mVertices = new aiVector3D[per_mat_verts[it.first]]; + out->mNormals = new aiVector3D[per_mat_verts[it.first]]; //out->mNumFaces = 0 //out->mNumVertices = 0 @@ -775,8 +834,56 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co // } } + for (int i = 0; i < mesh->totpoly; ++i) { + + const MPoly& mf = mesh->mpoly[i]; + + aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ]; + aiFace& f = out->mFaces[out->mNumFaces++]; + + f.mIndices = new unsigned int[ f.mNumIndices = mf.totloop ]; + aiVector3D* vo = out->mVertices + out->mNumVertices; + aiVector3D* vn = out->mNormals + out->mNumVertices; + + // XXX we can't fold this easily, because we are restricted + // to the member names from the BLEND file (v1,v2,v3,v4) + // which are assigned by the genblenddna.py script and + // cannot be changed without breaking the entire + // import process. + for (int j = 0;j < mf.totloop; ++j) + { + const MLoop& loop = mesh->mloop[mf.loopstart + j]; + + if (loop.v >= mesh->totvert) { + ThrowException("Vertex index out of range"); + } + + const MVert& v = mesh->mvert[loop.v]; + + vo->x = v.co[0]; + vo->y = v.co[1]; + vo->z = v.co[2]; + vn->x = v.no[0]; + vn->y = v.no[1]; + vn->z = v.no[2]; + f.mIndices[j] = out->mNumVertices++; + + ++vo; + ++vn; + + } + if (mf.totloop == 3) + { + out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; + } + else + { + out->mPrimitiveTypes |= aiPrimitiveType_POLYGON; + } + } + // collect texture coordinates, they're stored in a separate per-face buffer - if (mesh->mtface) { + if (mesh->mtface || mesh->mloopuv) { if (mesh->totface > static_cast<int> ( mesh->mtface.size())) { ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)"); } @@ -799,6 +906,20 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co vo->y = v->uv[i][1]; } } + + for (int i = 0; i < mesh->totpoly; ++i) { + const MPoly& v = mesh->mpoly[i]; + aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ]; + const aiFace& f = out->mFaces[out->mNumFaces++]; + + aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices]; + for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) { + const MLoopUV& uv = mesh->mloopuv[v.loopstart + j]; + vo->x = uv.uv[0]; + vo->y = uv.uv[1]; + } + + } } // collect texture coordinates, old-style (marked as deprecated in current blender sources) @@ -828,7 +949,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co } // collect vertex colors, stored separately as well - if (mesh->mcol) { + if (mesh->mcol || mesh->mloopcol) { if (mesh->totface > static_cast<int> ( (mesh->mcol.size()/4)) ) { ThrowException("Number of faces is larger than the corresponding color face array"); } @@ -855,29 +976,68 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co } for (unsigned int n = f.mNumIndices; n < 4; ++n); } + + for (int i = 0; i < mesh->totpoly; ++i) { + const MPoly& v = mesh->mpoly[i]; + aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ]; + const aiFace& f = out->mFaces[out->mNumFaces++]; + + aiColor4D* vo = &out->mColors[0][out->mNumVertices]; + for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) { + const MLoopCol& col = mesh->mloopcol[v.loopstart + j]; + vo->r = col.r; + vo->g = col.g; + vo->b = col.b; + vo->a = col.a; + } + + } + } return; } // ------------------------------------------------------------------------------------------------ -aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* /*obj*/, const Camera* /*mesh*/, ConversionData& /*conv_data*/) +aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* camera, ConversionData& /*conv_data*/) { ScopeGuard<aiCamera> out(new aiCamera()); - - return NULL ; //out.dismiss(); + out->mName = obj->id.name+2; + out->mPosition = aiVector3D(0.f, 0.f, 0.f); + out->mUp = aiVector3D(0.f, 1.f, 0.f); + out->mLookAt = aiVector3D(0.f, 0.f, -1.f); + return out.dismiss(); } // ------------------------------------------------------------------------------------------------ -aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* /*obj*/, const Lamp* /*mesh*/, ConversionData& /*conv_data*/) +aiLight* BlenderImporter::ConvertLight(const Scene& in, const Object* obj, const Lamp* lamp, ConversionData& conv_data) { ScopeGuard<aiLight> out(new aiLight()); + out->mName = obj->id.name+2; - return NULL ; //out.dismiss(); + switch (lamp->type) + { + case Lamp::Type_Local: + out->mType = aiLightSource_POINT; + break; + case Lamp::Type_Sun: + out->mType = aiLightSource_DIRECTIONAL; + + // blender orients directional lights as facing toward -z + out->mDirection = aiVector3D(0.f, 0.f, -1.f); + break; + default: + break; + } + + out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; + out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; + out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; + return out.dismiss(); } // ------------------------------------------------------------------------------------------------ -aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data) +aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform) { std::deque<const Object*> children; for(std::set<const Object*>::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) { @@ -961,16 +1121,12 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers for(unsigned int x = 0; x < 4; ++x) { for(unsigned int y = 0; y < 4; ++y) { - node->mTransformation[y][x] = obj->parentinv[x][y]; + node->mTransformation[y][x] = obj->obmat[x][y]; } } - aiMatrix4x4 m; - for(unsigned int x = 0; x < 4; ++x) { - for(unsigned int y = 0; y < 4; ++y) { - m[y][x] = obj->obmat[x][y]; - } - } + aiMatrix4x4 m = parentTransform; + m = m.Inverse(); node->mTransformation = m*node->mTransformation; @@ -978,7 +1134,7 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers node->mNumChildren = static_cast<unsigned int>(children.size()); aiNode** nd = node->mChildren = new aiNode*[node->mNumChildren](); for_each (const Object* nobj,children) { - *nd = ConvertNode(in,nobj,conv_data); + *nd = ConvertNode(in,nobj,conv_data,node->mTransformation * parentTransform); (*nd++)->mParent = node; } } diff --git a/src/3rdparty/assimp/code/BlenderLoader.h b/src/3rdparty/assimp/code/BlenderLoader.h index 21d5f661b..f7c1a08dc 100644 --- a/src/3rdparty/assimp/code/BlenderLoader.h +++ b/src/3rdparty/assimp/code/BlenderLoader.h @@ -145,7 +145,8 @@ private: // -------------------- aiNode* ConvertNode(const Blender::Scene& in, const Blender::Object* obj, - Blender::ConversionData& conv_info + Blender::ConversionData& conv_info, + const aiMatrix4x4& parentTransform ); // -------------------- diff --git a/src/3rdparty/assimp/code/BlenderScene.cpp b/src/3rdparty/assimp/code/BlenderScene.cpp index 77aa35994..39b57a508 100644 --- a/src/3rdparty/assimp/code/BlenderScene.cpp +++ b/src/3rdparty/assimp/code/BlenderScene.cpp @@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py */ #include "AssimpPCH.h" -#ifndef AI_BUILD_NO_BLEND_IMPORTER +#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #include "BlenderDNA.h" #include "BlenderScene.h" @@ -100,6 +100,7 @@ template <> void Structure :: Convert<MTex> ( ) const { + ReadField<ErrorPolicy_Igno>((short&)dest.mapto,"mapto",db); ReadField<ErrorPolicy_Igno>((int&)dest.blendtype,"blendtype",db); ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db); ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db); @@ -126,6 +127,7 @@ template <> void Structure :: Convert<MTex> ( ReadField<ErrorPolicy_Igno>(dest.specfac,"specfac",db); ReadField<ErrorPolicy_Igno>(dest.emitfac,"emitfac",db); ReadField<ErrorPolicy_Igno>(dest.hardfac,"hardfac",db); + ReadField<ErrorPolicy_Igno>(dest.norfac,"norfac",db); db.reader->IncPtr(size); } @@ -241,16 +243,36 @@ template <> void Structure :: Convert<Base> ( const FileDatabase& db ) const { - - { - boost::shared_ptr<Base> prev; - ReadFieldPtr<ErrorPolicy_Warn>(prev,"*prev",db); - dest.prev = prev.get(); - } - ReadFieldPtr<ErrorPolicy_Warn>(dest.next,"*next",db); - ReadFieldPtr<ErrorPolicy_Warn>(dest.object,"*object",db); - - db.reader->IncPtr(size); + // note: as per https://github.com/assimp/assimp/issues/128, + // reading the Object linked list recursively is prone to stack overflow. + // This structure converter is therefore an hand-written exception that + // does it iteratively. + + const int initial_pos = db.reader->GetCurrentPos(); + + std::pair<Base*, int> todo = std::make_pair(&dest, initial_pos); + for ( ;; ) { + + Base& cur_dest = *todo.first; + db.reader->SetCurrentPos(todo.second); + + // we know that this is a double-linked, circular list which we never + // traverse backwards, so don't bother resolving the back links. + cur_dest.prev = NULL; + + ReadFieldPtr<ErrorPolicy_Warn>(cur_dest.object,"*object",db); + + // the return value of ReadFieldPtr indicates whether the object + // was already cached. In this case, we don't need to resolve + // it again. + if(!ReadFieldPtr<ErrorPolicy_Warn>(cur_dest.next,"*next",db, true) && cur_dest.next) { + todo = std::make_pair(&*cur_dest.next, db.reader->GetCurrentPos()); + continue; + } + break; + } + + db.reader->SetCurrentPos(initial_pos + size); } //-------------------------------------------------------------------------------- @@ -306,6 +328,27 @@ template <> void Structure :: Convert<Material> ( } //-------------------------------------------------------------------------------- +template <> void Structure :: Convert<MTexPoly> ( + MTexPoly& dest, + const FileDatabase& db + ) const +{ + + { + boost::shared_ptr<Image> tpage; + ReadFieldPtr<ErrorPolicy_Igno>(tpage,"*tpage",db); + dest.tpage = tpage.get(); + } + ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db); + ReadField<ErrorPolicy_Igno>(dest.transp,"transp",db); + ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db); + ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db); + ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db); + + db.reader->IncPtr(size); +} + +//-------------------------------------------------------------------------------- template <> void Structure :: Convert<Mesh> ( Mesh& dest, const FileDatabase& db @@ -316,6 +359,8 @@ template <> void Structure :: Convert<Mesh> ( ReadField<ErrorPolicy_Fail>(dest.totface,"totface",db); ReadField<ErrorPolicy_Fail>(dest.totedge,"totedge",db); ReadField<ErrorPolicy_Fail>(dest.totvert,"totvert",db); + ReadField<ErrorPolicy_Igno>(dest.totloop,"totloop",db); + ReadField<ErrorPolicy_Igno>(dest.totpoly,"totpoly",db); ReadField<ErrorPolicy_Igno>(dest.subdiv,"subdiv",db); ReadField<ErrorPolicy_Igno>(dest.subdivr,"subdivr",db); ReadField<ErrorPolicy_Igno>(dest.subsurftype,"subsurftype",db); @@ -325,6 +370,11 @@ template <> void Structure :: Convert<Mesh> ( ReadFieldPtr<ErrorPolicy_Igno>(dest.tface,"*tface",db); ReadFieldPtr<ErrorPolicy_Fail>(dest.mvert,"*mvert",db); ReadFieldPtr<ErrorPolicy_Warn>(dest.medge,"*medge",db); + ReadFieldPtr<ErrorPolicy_Igno>(dest.mloop,"*mloop",db); + ReadFieldPtr<ErrorPolicy_Igno>(dest.mloopuv,"*mloopuv",db); + ReadFieldPtr<ErrorPolicy_Igno>(dest.mloopcol,"*mloopcol",db); + ReadFieldPtr<ErrorPolicy_Igno>(dest.mpoly,"*mpoly",db); + ReadFieldPtr<ErrorPolicy_Igno>(dest.mtpoly,"*mtpoly",db); ReadFieldPtr<ErrorPolicy_Igno>(dest.dvert,"*dvert",db); ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db); ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db); @@ -358,6 +408,21 @@ template <> void Structure :: Convert<World> ( } //-------------------------------------------------------------------------------- +template <> void Structure :: Convert<MLoopCol> ( + MLoopCol& dest, + const FileDatabase& db + ) const +{ + + ReadField<ErrorPolicy_Igno>(dest.r,"r",db); + ReadField<ErrorPolicy_Igno>(dest.g,"g",db); + ReadField<ErrorPolicy_Igno>(dest.b,"b",db); + ReadField<ErrorPolicy_Igno>(dest.a,"a",db); + + db.reader->IncPtr(size); +} + +//-------------------------------------------------------------------------------- template <> void Structure :: Convert<MVert> ( MVert& dest, const FileDatabase& db @@ -390,6 +455,19 @@ template <> void Structure :: Convert<MEdge> ( } //-------------------------------------------------------------------------------- +template <> void Structure :: Convert<MLoopUV> ( + MLoopUV& dest, + const FileDatabase& db + ) const +{ + + ReadFieldArray<ErrorPolicy_Igno>(dest.uv,"uv",db); + ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db); + + db.reader->IncPtr(size); +} + +//-------------------------------------------------------------------------------- template <> void Structure :: Convert<GroupObject> ( GroupObject& dest, const FileDatabase& db @@ -417,6 +495,19 @@ template <> void Structure :: Convert<ListBase> ( } //-------------------------------------------------------------------------------- +template <> void Structure :: Convert<MLoop> ( + MLoop& dest, + const FileDatabase& db + ) const +{ + + ReadField<ErrorPolicy_Igno>(dest.v,"v",db); + ReadField<ErrorPolicy_Igno>(dest.e,"e",db); + + db.reader->IncPtr(size); +} + +//-------------------------------------------------------------------------------- template <> void Structure :: Convert<ModifierData> ( ModifierData& dest, const FileDatabase& db @@ -461,34 +552,16 @@ template <> void Structure :: Convert<MCol> ( } //-------------------------------------------------------------------------------- -template <> void Structure :: Convert<Image> ( - Image& dest, +template <> void Structure :: Convert<MPoly> ( + MPoly& dest, const FileDatabase& db ) const { - ReadField<ErrorPolicy_Fail>(dest.id,"id",db); - ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db); - ReadField<ErrorPolicy_Igno>(dest.ok,"ok",db); + ReadField<ErrorPolicy_Igno>(dest.loopstart,"loopstart",db); + ReadField<ErrorPolicy_Igno>(dest.totloop,"totloop",db); + ReadField<ErrorPolicy_Igno>(dest.mat_nr,"mat_nr",db); ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db); - ReadField<ErrorPolicy_Igno>(dest.source,"source",db); - ReadField<ErrorPolicy_Igno>(dest.type,"type",db); - ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db); - ReadField<ErrorPolicy_Igno>(dest.pad1,"pad1",db); - ReadField<ErrorPolicy_Igno>(dest.lastframe,"lastframe",db); - ReadField<ErrorPolicy_Igno>(dest.tpageflag,"tpageflag",db); - ReadField<ErrorPolicy_Igno>(dest.totbind,"totbind",db); - ReadField<ErrorPolicy_Igno>(dest.xrep,"xrep",db); - ReadField<ErrorPolicy_Igno>(dest.yrep,"yrep",db); - ReadField<ErrorPolicy_Igno>(dest.twsta,"twsta",db); - ReadField<ErrorPolicy_Igno>(dest.twend,"twend",db); - ReadFieldPtr<ErrorPolicy_Igno>(dest.packedfile,"*packedfile",db); - ReadField<ErrorPolicy_Igno>(dest.lastupdate,"lastupdate",db); - ReadField<ErrorPolicy_Igno>(dest.lastused,"lastused",db); - ReadField<ErrorPolicy_Igno>(dest.animspeed,"animspeed",db); - ReadField<ErrorPolicy_Igno>(dest.gen_x,"gen_x",db); - ReadField<ErrorPolicy_Igno>(dest.gen_y,"gen_y",db); - ReadField<ErrorPolicy_Igno>(dest.gen_type,"gen_type",db); db.reader->IncPtr(size); } @@ -530,7 +603,7 @@ template <> void Structure :: Convert<Tex> ( const FileDatabase& db ) const { - + ReadField<ErrorPolicy_Igno>((short&)dest.imaflag,"imaflag",db); ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db); ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db); @@ -569,6 +642,39 @@ template <> void Structure :: Convert<MirrorModifierData> ( } //-------------------------------------------------------------------------------- +template <> void Structure :: Convert<Image> ( + Image& dest, + const FileDatabase& db + ) const +{ + + ReadField<ErrorPolicy_Fail>(dest.id,"id",db); + ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db); + ReadField<ErrorPolicy_Igno>(dest.ok,"ok",db); + ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db); + ReadField<ErrorPolicy_Igno>(dest.source,"source",db); + ReadField<ErrorPolicy_Igno>(dest.type,"type",db); + ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db); + ReadField<ErrorPolicy_Igno>(dest.pad1,"pad1",db); + ReadField<ErrorPolicy_Igno>(dest.lastframe,"lastframe",db); + ReadField<ErrorPolicy_Igno>(dest.tpageflag,"tpageflag",db); + ReadField<ErrorPolicy_Igno>(dest.totbind,"totbind",db); + ReadField<ErrorPolicy_Igno>(dest.xrep,"xrep",db); + ReadField<ErrorPolicy_Igno>(dest.yrep,"yrep",db); + ReadField<ErrorPolicy_Igno>(dest.twsta,"twsta",db); + ReadField<ErrorPolicy_Igno>(dest.twend,"twend",db); + ReadFieldPtr<ErrorPolicy_Igno>(dest.packedfile,"*packedfile",db); + ReadField<ErrorPolicy_Igno>(dest.lastupdate,"lastupdate",db); + ReadField<ErrorPolicy_Igno>(dest.lastused,"lastused",db); + ReadField<ErrorPolicy_Igno>(dest.animspeed,"animspeed",db); + ReadField<ErrorPolicy_Igno>(dest.gen_x,"gen_x",db); + ReadField<ErrorPolicy_Igno>(dest.gen_y,"gen_y",db); + ReadField<ErrorPolicy_Igno>(dest.gen_type,"gen_type",db); + + db.reader->IncPtr(size); +} + +//-------------------------------------------------------------------------------- void DNA::RegisterConverters() { converters["Object"] = DNA::FactoryPair( &Structure::Allocate<Object>, &Structure::Convert<Object> ); @@ -583,22 +689,27 @@ void DNA::RegisterConverters() { converters["Base"] = DNA::FactoryPair( &Structure::Allocate<Base>, &Structure::Convert<Base> ); converters["MTFace"] = DNA::FactoryPair( &Structure::Allocate<MTFace>, &Structure::Convert<MTFace> ); converters["Material"] = DNA::FactoryPair( &Structure::Allocate<Material>, &Structure::Convert<Material> ); + converters["MTexPoly"] = DNA::FactoryPair( &Structure::Allocate<MTexPoly>, &Structure::Convert<MTexPoly> ); converters["Mesh"] = DNA::FactoryPair( &Structure::Allocate<Mesh>, &Structure::Convert<Mesh> ); converters["MDeformVert"] = DNA::FactoryPair( &Structure::Allocate<MDeformVert>, &Structure::Convert<MDeformVert> ); converters["World"] = DNA::FactoryPair( &Structure::Allocate<World>, &Structure::Convert<World> ); + converters["MLoopCol"] = DNA::FactoryPair( &Structure::Allocate<MLoopCol>, &Structure::Convert<MLoopCol> ); converters["MVert"] = DNA::FactoryPair( &Structure::Allocate<MVert>, &Structure::Convert<MVert> ); converters["MEdge"] = DNA::FactoryPair( &Structure::Allocate<MEdge>, &Structure::Convert<MEdge> ); + converters["MLoopUV"] = DNA::FactoryPair( &Structure::Allocate<MLoopUV>, &Structure::Convert<MLoopUV> ); converters["GroupObject"] = DNA::FactoryPair( &Structure::Allocate<GroupObject>, &Structure::Convert<GroupObject> ); converters["ListBase"] = DNA::FactoryPair( &Structure::Allocate<ListBase>, &Structure::Convert<ListBase> ); + converters["MLoop"] = DNA::FactoryPair( &Structure::Allocate<MLoop>, &Structure::Convert<MLoop> ); converters["ModifierData"] = DNA::FactoryPair( &Structure::Allocate<ModifierData>, &Structure::Convert<ModifierData> ); converters["ID"] = DNA::FactoryPair( &Structure::Allocate<ID>, &Structure::Convert<ID> ); converters["MCol"] = DNA::FactoryPair( &Structure::Allocate<MCol>, &Structure::Convert<MCol> ); - converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> ); + converters["MPoly"] = DNA::FactoryPair( &Structure::Allocate<MPoly>, &Structure::Convert<MPoly> ); converters["Scene"] = DNA::FactoryPair( &Structure::Allocate<Scene>, &Structure::Convert<Scene> ); converters["Library"] = DNA::FactoryPair( &Structure::Allocate<Library>, &Structure::Convert<Library> ); converters["Tex"] = DNA::FactoryPair( &Structure::Allocate<Tex>, &Structure::Convert<Tex> ); converters["Camera"] = DNA::FactoryPair( &Structure::Allocate<Camera>, &Structure::Convert<Camera> ); converters["MirrorModifierData"] = DNA::FactoryPair( &Structure::Allocate<MirrorModifierData>, &Structure::Convert<MirrorModifierData> ); + converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> ); } diff --git a/src/3rdparty/assimp/code/BlenderScene.h b/src/3rdparty/assimp/code/BlenderScene.h index a3a4920bb..37ad282f3 100644 --- a/src/3rdparty/assimp/code/BlenderScene.h +++ b/src/3rdparty/assimp/code/BlenderScene.h @@ -94,6 +94,7 @@ namespace Assimp { struct Object; struct MTex; +struct Image; #define AI_BLEND_MESH_MAX_VERTS 2000000000L @@ -157,6 +158,38 @@ struct MEdge : ElemBase { }; // ------------------------------------------------------------------------------- +struct MLoop : ElemBase { + int v, e; +}; + +// ------------------------------------------------------------------------------- +struct MLoopUV : ElemBase { + float uv[2]; + int flag; +}; + +// ------------------------------------------------------------------------------- +// Note that red and blue are not swapped, as with MCol +struct MLoopCol : ElemBase { + char r, g, b, a; +}; + +// ------------------------------------------------------------------------------- +struct MPoly : ElemBase { + int loopstart; + int totloop; + short mat_nr; + char flag; +}; + +// ------------------------------------------------------------------------------- +struct MTexPoly : ElemBase { + Image* tpage; + char flag, transp; + short mode, tile, pad; +}; + +// ------------------------------------------------------------------------------- struct MCol : ElemBase { char r,g,b,a FAIL; }; @@ -235,6 +268,8 @@ struct Mesh : ElemBase { int totface FAIL; int totedge FAIL; int totvert FAIL; + int totloop; + int totpoly; short subdiv; short subdivr; @@ -246,6 +281,11 @@ struct Mesh : ElemBase { vector<TFace> tface; vector<MVert> mvert FAIL; vector<MEdge> medge WARN; + vector<MLoop> mloop; + vector<MLoopUV> mloopuv; + vector<MLoopCol> mloopcol; + vector<MPoly> mpoly; + vector<MTexPoly> mtpoly; vector<MDeformVert> dvert; vector<MCol> mcol; @@ -558,6 +598,18 @@ struct Tex : ElemBase { ,Type_VOXELDATA = 15 }; + enum ImageFlags { + ImageFlags_INTERPOL = 1 + ,ImageFlags_USEALPHA = 2 + ,ImageFlags_MIPMAP = 4 + ,ImageFlags_IMAROT = 16 + ,ImageFlags_CALCALPHA = 32 + ,ImageFlags_NORMALMAP = 2048 + ,ImageFlags_GAUSS_MIP = 4096 + ,ImageFlags_FILTER_MIN = 8192 + ,ImageFlags_DERIVATIVEMAP = 16384 + }; + ID id FAIL; // AnimData *adt; @@ -578,7 +630,8 @@ struct Tex : ElemBase { //short noisedepth, noisetype; //short noisebasis, noisebasis2; - //short imaflag, flag; + //short flag; + ImageFlags imaflag; Type type FAIL; //short stype; @@ -645,7 +698,25 @@ struct MTex : ElemBase { ,BlendType_BLEND_COLOR = 13 }; - // short texco, mapto, maptoneg; + enum MapType { + MapType_COL = 1 + ,MapType_NORM = 2 + ,MapType_COLSPEC = 4 + ,MapType_COLMIR = 8 + ,MapType_REF = 16 + ,MapType_SPEC = 32 + ,MapType_EMIT = 64 + ,MapType_ALPHA = 128 + ,MapType_HAR = 256 + ,MapType_RAYMIRR = 512 + ,MapType_TRANSLU = 1024 + ,MapType_AMB = 2048 + ,MapType_DISPLACE = 4096 + ,MapType_WARP = 8192 + }; + + // short texco, maptoneg; + MapType mapto; BlendType blendtype; boost::shared_ptr<Object> object; @@ -665,7 +736,8 @@ struct MTex : ElemBase { //float colfac, varfac; - //float norfac, dispfac, warpfac; + float norfac; + //float dispfac, warpfac; float colspecfac, mirrfac, alphafac; float difffac, specfac, emitfac, hardfac; //float raymirrfac, translfac, ambfac; diff --git a/src/3rdparty/assimp/code/BlenderSceneGen.h b/src/3rdparty/assimp/code/BlenderSceneGen.h index 99c673189..b8e0b6b22 100644 --- a/src/3rdparty/assimp/code/BlenderSceneGen.h +++ b/src/3rdparty/assimp/code/BlenderSceneGen.h @@ -120,6 +120,12 @@ template <> void Structure :: Convert<Material> ( ) const ; +template <> void Structure :: Convert<MTexPoly> ( + MTexPoly& dest, + const FileDatabase& db + ) const +; + template <> void Structure :: Convert<Mesh> ( Mesh& dest, const FileDatabase& db @@ -138,6 +144,12 @@ template <> void Structure :: Convert<World> ( ) const ; +template <> void Structure :: Convert<MLoopCol> ( + MLoopCol& dest, + const FileDatabase& db + ) const +; + template <> void Structure :: Convert<MVert> ( MVert& dest, const FileDatabase& db @@ -150,6 +162,12 @@ template <> void Structure :: Convert<MEdge> ( ) const ; +template <> void Structure :: Convert<MLoopUV> ( + MLoopUV& dest, + const FileDatabase& db + ) const +; + template <> void Structure :: Convert<GroupObject> ( GroupObject& dest, const FileDatabase& db @@ -162,6 +180,12 @@ template <> void Structure :: Convert<ListBase> ( ) const ; +template <> void Structure :: Convert<MLoop> ( + MLoop& dest, + const FileDatabase& db + ) const +; + template <> void Structure :: Convert<ModifierData> ( ModifierData& dest, const FileDatabase& db @@ -180,8 +204,8 @@ template <> void Structure :: Convert<MCol> ( ) const ; -template <> void Structure :: Convert<Image> ( - Image& dest, +template <> void Structure :: Convert<MPoly> ( + MPoly& dest, const FileDatabase& db ) const ; @@ -216,6 +240,12 @@ template <> void Structure :: Convert<MirrorModifierData> ( ) const ; +template <> void Structure :: Convert<Image> ( + Image& dest, + const FileDatabase& db + ) const +; + } } diff --git a/src/3rdparty/assimp/code/BlenderTessellator.cpp b/src/3rdparty/assimp/code/BlenderTessellator.cpp new file mode 100644 index 000000000..ffe794951 --- /dev/null +++ b/src/3rdparty/assimp/code/BlenderTessellator.cpp @@ -0,0 +1,520 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2013, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file BlenderTessellator.cpp + * @brief A simple tessellation wrapper + */ + +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER + +#include "BlenderDNA.h" +#include "BlenderScene.h" +#include "BlenderBMesh.h" +#include "BlenderTessellator.h" + +static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3; + +#if ASSIMP_BLEND_WITH_GLU_TESSELLATE + +namspace Assimp +{ + template< > const std::string LogFunctions< BlenderTessellatorGL >::log_prefix = "BLEND_TESS_GL: "; +} + +using namespace Assimp; +using namespace Assimp::Blender; + +#ifndef CALLBACK +#define CALLBACK +#endif + +// ------------------------------------------------------------------------------------------------ +BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ): + converter( &converter ) +{ +} + +// ------------------------------------------------------------------------------------------------ +BlenderTessellatorGL::~BlenderTessellatorGL( ) +{ +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices ) +{ + AssertVertexCount( vertexCount ); + + std::vector< VertexGL > polyLoopGL; + GenerateLoopVerts( polyLoopGL, polyLoop, vertexCount, vertices ); + + TessDataGL tessData; + Tesssellate( polyLoopGL, tessData ); + + TriangulateDrawCalls( tessData ); +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::AssertVertexCount( int vertexCount ) +{ + if ( vertexCount <= 4 ) + { + ThrowException( "Expected more than 4 vertices for tessellation" ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::GenerateLoopVerts( std::vector< VertexGL >& polyLoopGL, const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices ) +{ + for ( int i = 0; i < vertexCount; ++i ) + { + const MLoop& loopItem = polyLoop[ i ]; + const MVert& vertex = vertices[ loopItem.v ]; + polyLoopGL.push_back( VertexGL( vertex.co[ 0 ], vertex.co[ 1 ], vertex.co[ 2 ], loopItem.v, BLEND_TESS_MAGIC ) ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::Tesssellate( std::vector< VertexGL >& polyLoopGL, TessDataGL& tessData ) +{ + GLUtesselator* tessellator = gluNewTess( ); + gluTessCallback( tessellator, GLU_TESS_BEGIN_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateBegin ) ); + gluTessCallback( tessellator, GLU_TESS_END_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEnd ) ); + gluTessCallback( tessellator, GLU_TESS_VERTEX_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateVertex ) ); + gluTessCallback( tessellator, GLU_TESS_COMBINE_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateCombine ) ); + gluTessCallback( tessellator, GLU_TESS_EDGE_FLAG_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEdgeFlag ) ); + gluTessCallback( tessellator, GLU_TESS_ERROR_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateError ) ); + gluTessProperty( tessellator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO ); + + gluTessBeginPolygon( tessellator, &tessData ); + gluTessBeginContour( tessellator ); + + for ( unsigned int i = 0; i < polyLoopGL.size( ); ++i ) + { + gluTessVertex( tessellator, reinterpret_cast< GLdouble* >( &polyLoopGL[ i ] ), &polyLoopGL[ i ] ); + } + + gluTessEndContour( tessellator ); + gluTessEndPolygon( tessellator ); +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData ) +{ + // NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically + // need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case + // GLU tessellate changes or tristrips and fans are wanted. + // See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml + for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i ) + { + const DrawCallGL& drawCallGL = tessData.drawCalls[ i ]; + const VertexGL* vertices = &tessData.vertices[ drawCallGL.baseVertex ]; + if ( drawCallGL.drawMode == GL_TRIANGLES ) + { + MakeFacesFromTris( vertices, drawCallGL.vertexCount ); + } + else if ( drawCallGL.drawMode == GL_TRIANGLE_STRIP ) + { + MakeFacesFromTriStrip( vertices, drawCallGL.vertexCount ); + } + else if ( drawCallGL.drawMode == GL_TRIANGLE_FAN ) + { + MakeFacesFromTriFan( vertices, drawCallGL.vertexCount ); + } + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount ) +{ + int triangleCount = vertexCount / 3; + for ( int i = 0; i < triangleCount; ++i ) + { + int vertexBase = i * 3; + converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount ) +{ + int triangleCount = vertexCount - 2; + for ( int i = 0; i < triangleCount; ++i ) + { + int vertexBase = i; + converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount ) +{ + int triangleCount = vertexCount - 2; + for ( int i = 0; i < triangleCount; ++i ) + { + int vertexBase = i; + converter->AddFace( vertices[ 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::TessellateBegin( GLenum drawModeGL, void* userData ) +{ + TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData ); + tessData.drawCalls.push_back( DrawCallGL( drawModeGL, tessData.vertices.size( ) ) ); +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::TessellateEnd( void* ) +{ + // Do nothing +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::TessellateVertex( const void* vtxData, void* userData ) +{ + TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData ); + + const VertexGL& vertex = *reinterpret_cast< const VertexGL* >( vtxData ); + if ( vertex.magic != BLEND_TESS_MAGIC ) + { + ThrowException( "Point returned by GLU Tessellate was probably not one of ours. This indicates we need a new way to store vertex information" ); + } + tessData.vertices.push_back( vertex ); + if ( tessData.drawCalls.size( ) == 0 ) + { + ThrowException( "\"Vertex\" callback received before \"Begin\"" ); + } + ++( tessData.drawCalls.back( ).vertexCount ); +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData ) +{ + ThrowException( "Intersected polygon loops are not yet supported" ); +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::TessellateEdgeFlag( GLboolean, void* ) +{ + // Do nothing +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* ) +{ + ThrowException( reinterpret_cast< const char* >( gluErrorString( errorCode ) ) ); +} + +#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE + +#if ASSIMP_BLEND_WITH_POLY_2_TRI + +namespace Assimp +{ + template< > const std::string LogFunctions< BlenderTessellatorP2T >::log_prefix = "BLEND_TESS_P2T: "; +} + +using namespace Assimp; +using namespace Assimp::Blender; + +// ------------------------------------------------------------------------------------------------ +BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ): + converter( &converter ) +{ +} + +// ------------------------------------------------------------------------------------------------ +BlenderTessellatorP2T::~BlenderTessellatorP2T( ) +{ +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorP2T::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices ) +{ + AssertVertexCount( vertexCount ); + + // NOTE - We have to hope that points in a Blender polygon are roughly on the same plane. + // There may be some triangulation artifacts if they are wildly different. + + std::vector< PointP2T > points; + Copy3DVertices( polyLoop, vertexCount, vertices, points ); + + PlaneP2T plane = FindLLSQPlane( points ); + + aiMatrix4x4 transform = GeneratePointTransformMatrix( plane ); + + TransformAndFlattenVectices( transform, points ); + + std::vector< p2t::Point* > pointRefs; + ReferencePoints( points, pointRefs ); + + p2t::CDT cdt( pointRefs ); + + cdt.Triangulate( ); + std::vector< p2t::Triangle* > triangles = cdt.GetTriangles( ); + + MakeFacesFromTriangles( triangles ); +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorP2T::AssertVertexCount( int vertexCount ) +{ + if ( vertexCount <= 4 ) + { + ThrowException( "Expected more than 4 vertices for tessellation" ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices, std::vector< PointP2T >& points ) const +{ + points.resize( vertexCount ); + for ( int i = 0; i < vertexCount; ++i ) + { + const MLoop& loop = polyLoop[ i ]; + const MVert& vert = vertices[ loop.v ]; + + PointP2T& point = points[ i ]; + point.point3D.Set( vert.co[ 0 ], vert.co[ 1 ], vert.co[ 2 ] ); + point.index = loop.v; + point.magic = BLEND_TESS_MAGIC; + } +} + +// ------------------------------------------------------------------------------------------------ +aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const +{ + aiVector3D sideA( 1.0f, 0.0f, 0.0f ); + if ( fabs( plane.normal * sideA ) > 0.999f ) + { + sideA = aiVector3D( 0.0f, 1.0f, 0.0f ); + } + + aiVector3D sideB( plane.normal ^ sideA ); + sideB.Normalize( ); + sideA = sideB ^ plane.normal; + + aiMatrix4x4 result; + result.a1 = sideA.x; + result.a2 = sideA.y; + result.a3 = sideA.z; + result.b1 = sideB.x; + result.b2 = sideB.y; + result.b3 = sideB.z; + result.c1 = plane.normal.x; + result.c2 = plane.normal.y; + result.c3 = plane.normal.z; + result.a4 = plane.centre.x; + result.b4 = plane.centre.y; + result.c4 = plane.centre.z; + result.Inverse( ); + + return result; +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const +{ + for ( unsigned int i = 0; i < vertices.size( ); ++i ) + { + PointP2T& point = vertices[ i ]; + point.point3D = transform * point.point3D; + point.point2D.set( point.point3D.y, point.point3D.z ); + } +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const +{ + pointRefs.resize( points.size( ) ); + for ( unsigned int i = 0; i < points.size( ); ++i ) + { + pointRefs[ i ] = &points[ i ].point2D; + } +} + +// ------------------------------------------------------------------------------------------------ +// Yes this is filthy... but we have no choice +#define OffsetOf( Class, Member ) ( static_cast< unsigned int >( \ + reinterpret_cast<uint8_t*>(&( reinterpret_cast< Class* >( NULL )->*( &Class::Member ) )) - \ + static_cast<uint8_t*>(NULL) ) ) + +inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const +{ + unsigned int pointOffset = OffsetOf( PointP2T, point2D ); + PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset ); + if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) ) + { + ThrowException( "Point returned by poly2tri was probably not one of ours. This indicates we need a new way to store vertex information" ); + } + return pointStruct; +} + +// ------------------------------------------------------------------------------------------------ +void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const +{ + for ( unsigned int i = 0; i < triangles.size( ); ++i ) + { + p2t::Triangle& Triangle = *triangles[ i ]; + + PointP2T& pointA = GetActualPointStructure( *Triangle.GetPoint( 0 ) ); + PointP2T& pointB = GetActualPointStructure( *Triangle.GetPoint( 1 ) ); + PointP2T& pointC = GetActualPointStructure( *Triangle.GetPoint( 2 ) ); + + converter->AddFace( pointA.index, pointB.index, pointC.index ); + } +} + +// ------------------------------------------------------------------------------------------------ +inline float p2tMax( float a, float b ) +{ + return a > b ? a : b; +} + +// ------------------------------------------------------------------------------------------------ +// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html +float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) const +{ + float result = 0.0f; + + for ( int x = 0; x < 3; ++x ) + { + for ( int y = 0; y < 3; ++y ) + { + result = p2tMax( fabs( mtx[ x ][ y ] ), result ); + } + } + + return result; +} + +// ------------------------------------------------------------------------------------------------ +// Aparently Assimp doesn't have matrix scaling +aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const +{ + aiMatrix3x3 result; + + for ( int x = 0; x < 3; ++x ) + { + for ( int y = 0; y < 3; ++y ) + { + result[ x ][ y ] = mtx[ x ][ y ] * scale; + } + } + + return result; +} + + +// ------------------------------------------------------------------------------------------------ +// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html +aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const +{ + float scale = FindLargestMatrixElem( mtx ); + aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale ); + mc = mc * mc * mc; + + aiVector3D v( 1.0f ); + aiVector3D lastV = v; + for ( int i = 0; i < 100; ++i ) + { + v = mc * v; + v.Normalize( ); + if ( ( v - lastV ).SquareLength( ) < 1e-16f ) + { + break; + } + lastV = v; + } + return v; +} + +// ------------------------------------------------------------------------------------------------ +// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html +PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& points ) const +{ + PlaneP2T result; + + aiVector3D sum( 0.0f ); + for ( unsigned int i = 0; i < points.size( ); ++i ) + { + sum += points[ i ].point3D; + } + result.centre = sum * ( 1.0f / points.size( ) ); + + float sumXX = 0.0f; + float sumXY = 0.0f; + float sumXZ = 0.0f; + float sumYY = 0.0f; + float sumYZ = 0.0f; + float sumZZ = 0.0f; + for ( unsigned int i = 0; i < points.size( ); ++i ) + { + aiVector3D offset = points[ i ].point3D - result.centre; + sumXX += offset.x * offset.x; + sumXY += offset.x * offset.y; + sumXZ += offset.x * offset.z; + sumYY += offset.y * offset.y; + sumYZ += offset.y * offset.z; + sumZZ += offset.z * offset.z; + } + + aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ ); + + float det = mtx.Determinant( ); + if ( det == 0.0f ) + { + result.normal = aiVector3D( 0.0f ); + } + else + { + aiMatrix3x3 invMtx = mtx; + invMtx.Inverse( ); + result.normal = GetEigenVectorFromLargestEigenValue( invMtx ); + } + + return result; +} + +#endif // ASSIMP_BLEND_WITH_POLY_2_TRI + +#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER diff --git a/src/3rdparty/assimp/code/BlenderTessellator.h b/src/3rdparty/assimp/code/BlenderTessellator.h new file mode 100644 index 000000000..0d85e404b --- /dev/null +++ b/src/3rdparty/assimp/code/BlenderTessellator.h @@ -0,0 +1,208 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2013, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file BlenderTessellator.h + * @brief A simple tessellation wrapper + */ +#ifndef INCLUDED_AI_BLEND_TESSELLATOR_H +#define INCLUDED_AI_BLEND_TESSELLATOR_H + +// Use these to toggle between GLU Tessellate or poly2tri +// Note (acg) keep GLU Tesselate disabled by default - if it is turned on, +// assimp needs to be linked against GLU, which is currently not yet +// made configurable in CMake and potentially not wanted by most users +// as it requires a Gl environment. +#ifndef ASSIMP_BLEND_WITH_GLU_TESSELLATE +# define ASSIMP_BLEND_WITH_GLU_TESSELLATE 0 +#endif + +#ifndef ASSIMP_BLEND_WITH_POLY_2_TRI +# define ASSIMP_BLEND_WITH_POLY_2_TRI 1 +#endif + +#include "LogAux.h" + +#if ASSIMP_BLEND_WITH_GLU_TESSELLATE + +#if defined( WIN32 ) || defined( _WIN32 ) || defined( _MSC_VER ) +#include <windows.h> +#endif +#include <GL/glu.h> + +namespace Assimp +{ + class BlenderBMeshConverter; + + // TinyFormatter.h + namespace Formatter + { + template < typename T,typename TR, typename A > class basic_formatter; + typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format; + } + + // BlenderScene.h + namespace Blender + { + struct MLoop; + struct MVert; + + struct VertexGL + { + GLdouble X; + GLdouble Y; + GLdouble Z; + int index; + int magic; + + VertexGL( GLdouble X, GLdouble Y, GLdouble Z, int index, int magic ): X( X ), Y( Y ), Z( Z ), index( index ), magic( magic ) { } + }; + + struct DrawCallGL + { + GLenum drawMode; + int baseVertex; + int vertexCount; + + DrawCallGL( GLenum drawMode, int baseVertex ): drawMode( drawMode ), baseVertex( baseVertex ), vertexCount( 0 ) { } + }; + + struct TessDataGL + { + std::vector< DrawCallGL > drawCalls; + std::vector< VertexGL > vertices; + }; + } + + class BlenderTessellatorGL: public LogFunctions< BlenderTessellatorGL > + { + public: + BlenderTessellatorGL( BlenderBMeshConverter& converter ); + ~BlenderTessellatorGL( ); + + void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices ); + + private: + void AssertVertexCount( int vertexCount ); + void GenerateLoopVerts( std::vector< Blender::VertexGL >& polyLoopGL, const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices ); + void Tesssellate( std::vector< Blender::VertexGL >& polyLoopGL, Blender::TessDataGL& tessData ); + void TriangulateDrawCalls( const Blender::TessDataGL& tessData ); + void MakeFacesFromTris( const Blender::VertexGL* vertices, int vertexCount ); + void MakeFacesFromTriStrip( const Blender::VertexGL* vertices, int vertexCount ); + void MakeFacesFromTriFan( const Blender::VertexGL* vertices, int vertexCount ); + + static void TessellateBegin( GLenum drawModeGL, void* userData ); + static void TessellateEnd( void* userData ); + static void TessellateVertex( const void* vtxData, void* userData ); + static void TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData ); + static void TessellateEdgeFlag( GLboolean edgeFlag, void* userData ); + static void TessellateError( GLenum errorCode, void* userData ); + + BlenderBMeshConverter* converter; + }; +} // end of namespace Assimp + +#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE + +#if ASSIMP_BLEND_WITH_POLY_2_TRI + +#include "../contrib/poly2tri/poly2tri/poly2tri.h" + +namespace Assimp +{ + class BlenderBMeshConverter; + + // TinyFormatter.h + namespace Formatter + { + template < typename T,typename TR, typename A > class basic_formatter; + typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format; + } + + // BlenderScene.h + namespace Blender + { + struct MLoop; + struct MVert; + + struct PointP2T + { + aiVector3D point3D; + p2t::Point point2D; + int magic; + int index; + }; + + struct PlaneP2T + { + aiVector3D centre; + aiVector3D normal; + }; + } + + class BlenderTessellatorP2T: public LogFunctions< BlenderTessellatorP2T > + { + public: + BlenderTessellatorP2T( BlenderBMeshConverter& converter ); + ~BlenderTessellatorP2T( ); + + void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices ); + + private: + void AssertVertexCount( int vertexCount ); + void Copy3DVertices( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices, std::vector< Blender::PointP2T >& targetVertices ) const; + aiMatrix4x4 GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const; + void TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const; + void ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const; + inline Blender::PointP2T& GetActualPointStructure( p2t::Point& point ) const; + void MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const; + + // Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html + float FindLargestMatrixElem( const aiMatrix3x3& mtx ) const; + aiMatrix3x3 ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const; + aiVector3D GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const; + Blender::PlaneP2T FindLLSQPlane( const std::vector< Blender::PointP2T >& points ) const; + + BlenderBMeshConverter* converter; + }; +} // end of namespace Assimp + +#endif // ASSIMP_BLEND_WITH_POLY_2_TRI + +#endif // INCLUDED_AI_BLEND_TESSELLATOR_H diff --git a/src/3rdparty/assimp/code/BlobIOSystem.h b/src/3rdparty/assimp/code/BlobIOSystem.h index 2371f1f55..655768c33 100644 --- a/src/3rdparty/assimp/code/BlobIOSystem.h +++ b/src/3rdparty/assimp/code/BlobIOSystem.h @@ -88,9 +88,9 @@ public: // ------------------------------------------------------------------- - virtual size_t Read(void* /*pvBuffer*/, - size_t /*pSize*/, - size_t /*pCount*/) + virtual size_t Read( void *, + size_t, + size_t ) { return 0; } diff --git a/src/3rdparty/assimp/code/BoostWorkaround/boost/lexical_cast.hpp b/src/3rdparty/assimp/code/BoostWorkaround/boost/lexical_cast.hpp index 2c97ab649..af91b011f 100644 --- a/src/3rdparty/assimp/code/BoostWorkaround/boost/lexical_cast.hpp +++ b/src/3rdparty/assimp/code/BoostWorkaround/boost/lexical_cast.hpp @@ -3,6 +3,8 @@ #ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST #define __AI_BOOST_WORKAROUND_LEXICAL_CAST +#include <sstream> + namespace boost { diff --git a/src/3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp b/src/3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp index 818a4a58c..0ff61d9c3 100644 --- a/src/3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp +++ b/src/3rdparty/assimp/code/BoostWorkaround/boost/tuple/tuple.hpp @@ -175,13 +175,13 @@ namespace boost { // Get a specific tuple element template <unsigned N> typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () { - return m.template get<N>(); + return m.template get<N>(); } // ... and the const version template <unsigned N> const typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () const { - return m.template get<N>(); + return m.template get<N>(); } @@ -208,14 +208,14 @@ namespace boost { template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4> inline typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get ( tuple<T0,T1,T2,T3,T4>& m) { - return m.template get<N>(); + return m.template get<N>(); } // ... and the const version template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4> inline const typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get ( const tuple<T0,T1,T2,T3,T4>& m) { - return m.template get<N>(); + return m.template get<N>(); } // Constructs a tuple with 5 elements @@ -224,11 +224,11 @@ namespace boost { const T1& t1,const T2& t2,const T3& t3,const T4& t4) { tuple <T0,T1,T2,T3,T4> t; - t.template get<0>() = t0; - t.template get<1>() = t1; - t.template get<2>() = t2; - t.template get<3>() = t3; - t.template get<4>() = t4; + t.template get<0>() = t0; + t.template get<1>() = t1; + t.template get<2>() = t2; + t.template get<3>() = t3; + t.template get<4>() = t4; return t; } @@ -237,10 +237,10 @@ namespace boost { inline tuple <T0,T1,T2,T3> make_tuple (const T0& t0, const T1& t1,const T2& t2,const T3& t3) { tuple <T0,T1,T2,T3> t; - t.template get<0>() = t0; - t.template get<1>() = t1; - t.template get<2>() = t2; - t.template get<3>() = t3; + t.template get<0>() = t0; + t.template get<1>() = t1; + t.template get<2>() = t2; + t.template get<3>() = t3; return t; } @@ -249,31 +249,31 @@ namespace boost { inline tuple <T0,T1,T2> make_tuple (const T0& t0, const T1& t1,const T2& t2) { tuple <T0,T1,T2> t; - t.template get<0>() = t0; - t.template get<1>() = t1; - t.template get<2>() = t2; + t.template get<0>() = t0; + t.template get<1>() = t1; + t.template get<2>() = t2; return t; } - // Constructs a tuple with 2 elements (fucking idiot, use std::pair instead!) + // Constructs a tuple with 2 elements template <typename T0,typename T1> inline tuple <T0,T1> make_tuple (const T0& t0, const T1& t1) { tuple <T0,T1> t; - t.template get<0>() = t0; - t.template get<1>() = t1; + t.template get<0>() = t0; + t.template get<1>() = t1; return t; } - // Constructs a tuple with 1 elements (no comment ...) + // Constructs a tuple with 1 elements (well ...) template <typename T0> inline tuple <T0> make_tuple (const T0& t0) { tuple <T0> t; - t.template get<0>() = t0; + t.template get<0>() = t0; return t; } - // Constructs a tuple with 0 elements (ehm? Try http://www.promillerechner.net) + // Constructs a tuple with 0 elements (well ...) inline tuple <> make_tuple () { tuple <> t; return t; diff --git a/src/3rdparty/assimp/code/CMakeLists.txt b/src/3rdparty/assimp/code/CMakeLists.txt index f6691d58f..994904fdc 100644 --- a/src/3rdparty/assimp/code/CMakeLists.txt +++ b/src/3rdparty/assimp/code/CMakeLists.txt @@ -4,6 +4,7 @@ # 3) Add libassimp using the file lists (eliminates duplication of file names between # source groups and library command) # +cmake_minimum_required( VERSION 2.6 ) SET( HEADER_PATH ../include/assimp ) SET( COMPILER_HEADERS @@ -34,6 +35,7 @@ SET( PUBLIC_HEADERS ${HEADER_PATH}/quaternion.h ${HEADER_PATH}/quaternion.inl ${HEADER_PATH}/scene.h + ${HEADER_PATH}/metadata.h ${HEADER_PATH}/texture.h ${HEADER_PATH}/types.h ${HEADER_PATH}/vector2.h @@ -57,8 +59,6 @@ SET( PUBLIC_HEADERS SET( Core_SRCS Assimp.cpp - AssimpPCH.cpp - AssimpPCH.h ) SET( Boost_SRCS @@ -77,13 +77,13 @@ SOURCE_GROUP(Boost FILES ${Boost_SRCS}) SET( Logging_SRCS ${HEADER_PATH}/DefaultLogger.hpp - ${HEADER_PATH}/IOStream.hpp ${HEADER_PATH}/LogStream.hpp ${HEADER_PATH}/Logger.hpp ${HEADER_PATH}/NullLogger.hpp Win32DebugLogStream.h DefaultLogger.cpp FileLogStream.h + StdOStreamLogStream.h ) SOURCE_GROUP(Logging FILES ${Logging_SRCS}) @@ -108,8 +108,8 @@ SET( Common_SRCS Hash.h Importer.cpp IFF.h + MemoryIOWrapper.h ParsingUtils.h - StdOStreamLogStream.h StreamReader.h StringComparison.h SGSpatialSort.cpp @@ -141,6 +141,8 @@ SET( Common_SRCS TinyFormatter.h Profiler.h LogAux.h + Bitmap.cpp + Bitmap.h ) SOURCE_GROUP(Common FILES ${Common_SRCS}) @@ -237,11 +239,7 @@ SET( LWS_SRCS ) SOURCE_GROUP( LWS FILES ${LWS_SRCS}) -SET ( M3_SRCS - M3Importer.cpp - M3Importer.h -) -SOURCE_GROUP( M3 FILES ${M3_SRCS} ) + SET( MD2_SRCS MD2FileData.h @@ -323,8 +321,8 @@ SET( Obj_SRCS SOURCE_GROUP( Obj FILES ${Obj_SRCS}) SET( Ogre_SRCS - OgreImporter.hpp - OgreXmlHelper.hpp + OgreImporter.h + OgreParsingUtils.h OgreImporter.cpp OgreMaterial.cpp OgreMesh.cpp @@ -367,6 +365,10 @@ SET(BLENDER_SRCS BlenderIntermediate.h BlenderModifier.h BlenderModifier.cpp + BlenderBMesh.h + BlenderBMesh.cpp + BlenderTessellator.h + BlenderTessellator.cpp ) SOURCE_GROUP( BLENDER FILES ${BLENDER_SRCS}) @@ -381,9 +383,13 @@ SET(IFC_SRCS IFCMaterial.cpp IFCProfile.cpp IFCCurve.cpp + IFCBoolean.cpp + IFCOpenings.cpp STEPFile.h STEPFileReader.h STEPFileReader.cpp + STEPFileEncoding.cpp + STEPFileEncoding.h ) SOURCE_GROUP( IFC FILES ${IFC_SRCS}) @@ -394,6 +400,35 @@ SET( XGL_SRCS SOURCE_GROUP( XGL FILES ${XGL_SRCS}) +SET(FBX_SRCS + FBXImporter.cpp + FBXCompileConfig.h + FBXImporter.h + FBXParser.cpp + FBXParser.h + FBXTokenizer.cpp + FBXTokenizer.h + FBXImportSettings.h + FBXConverter.h + FBXConverter.cpp + FBXUtil.h + FBXUtil.cpp + FBXDocument.h + FBXDocument.cpp + FBXProperties.h + FBXProperties.cpp + FBXMeshGeometry.cpp + FBXMaterial.cpp + FBXModel.cpp + FBXAnimation.cpp + FBXNodeAttribute.cpp + FBXDeformer.cpp + FBXBinaryTokenizer.cpp + FBXDocumentUtil.cpp +) +SOURCE_GROUP( FBX FILES ${FBX_SRCS}) + + SET( PostProcessing_SRCS CalcTangentsProcess.cpp CalcTangentsProcess.h @@ -429,8 +464,6 @@ SET( PostProcessing_SRCS SortByPTypeProcess.h SplitLargeMeshes.cpp SplitLargeMeshes.h - TerragenLoader.cpp - TerragenLoader.h TextureTransform.cpp TextureTransform.h TriangulateProcess.cpp @@ -488,6 +521,12 @@ SET( STL_SRCS ) SOURCE_GROUP( STL FILES ${STL_SRCS}) +SET( Terragen_SRCS + TerragenLoader.cpp + TerragenLoader.h +) +SOURCE_GROUP( Terragen FILES ${Terragen_SRCS}) + SET( Unreal_SRCS UnrealLoader.cpp UnrealLoader.h @@ -566,17 +605,19 @@ SOURCE_GROUP( unzip FILES ${unzip_SRCS}) # VC2010 fixes -OPTION( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF ) -if( VC10_STDINT_FIX ) - ADD_DEFINITIONS( -D_STDINT ) -endif( VC10_STDINT_FIX ) +if(MSVC10) + OPTION( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF ) + if( VC10_STDINT_FIX ) + ADD_DEFINITIONS( -D_STDINT ) + endif( VC10_STDINT_FIX ) +endif(MSVC10) ADD_DEFINITIONS( -DASSIMP_BUILD_DLL_EXPORT ) -if ( MSVC80 OR MSVC90 OR MSVC10 ) +if ( MSVC ) ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS ) ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS ) -endif ( MSVC80 OR MSVC90 OR MSVC10 ) +endif ( MSVC ) if (UNZIP_FOUND) SET (unzip_compile_SRCS "") @@ -584,7 +625,7 @@ else (UNZIP_FOUND) SET (unzip_compile_SRCS ${unzip_SRCS}) endif (UNZIP_FOUND) -SET( assim_src +SET( assimp_src # Assimp Files ${Core_SRCS} ${Common_SRCS} @@ -605,7 +646,6 @@ SET( assim_src ${Irr_SRCS} ${LWO_SRCS} ${LWS_SRCS} - ${M3_SRCS} ${MD2_SRCS} ${MD3_SRCS} ${MD5_SRCS} @@ -622,6 +662,7 @@ SET( assim_src ${Raw_SRCS} ${SMD_SRCS} ${STL_SRCS} + ${Terragen_SRCS} ${Unreal_SRCS} ${XFile_SRCS} ${Extra_SRCS} @@ -631,6 +672,7 @@ SET( assim_src ${NDO_SRCS} ${IFC_SRCS} ${XGL_SRCS} + ${FBX_SRCS} # Third-party libraries ${IrrXML_SRCS} @@ -643,26 +685,30 @@ SET( assim_src ${PUBLIC_HEADERS} ${COMPILER_HEADERS} + + # Old precompiled header + # (removed because the precompiled header is not updated when visual studio switch configuration which leads to failed compilation. + # Moreover it's a drag to recompile assimp entirely each time a modification is made to one of the included header, which is definitely counter-productive.) + AssimpPCH.cpp ) -IF ( BUILD_STATIC_LIB ) - ADD_LIBRARY( assimp STATIC - ${assim_src} - ) -ELSE ( BUILD_STATIC_LIB ) - ADD_LIBRARY( assimp SHARED - ${assim_src} - ) -ENDIF ( BUILD_STATIC_LIB ) -SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${DEBUG_POSTFIX}) +#ADD_MSVC_PRECOMPILED_HEADER("AssimpPCH.h" "AssimpPCH.cpp" assimp_src) + +ADD_LIBRARY( assimp ${assimp_src} ) + +SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX}) TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES}) SET_TARGET_PROPERTIES( assimp PROPERTIES VERSION ${ASSIMP_VERSION} SOVERSION ${ASSIMP_SOVERSION} # use full version OUTPUT_NAME assimp${ASSIMP_LIBRARY_SUFFIX} - CLEAN_DIRECT_OUTPUT 1 ) + +if (APPLE) + SET_TARGET_PROPERTIES( assimp PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}") +endif() + # Build against external unzip, or add ../contrib/unzip so # assimp can #include "unzip.h" if (UNZIP_FOUND) @@ -672,6 +718,21 @@ else (UNZIP_FOUND) INCLUDE_DIRECTORIES("../contrib/unzip") endif (UNZIP_FOUND) -INSTALL( TARGETS assimp DESTINATION ${LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT}) -INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/assimp COMPONENT ${LIBASSIMP-DEV_COMPONENT}) -INSTALL( FILES ${COMPILER_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/assimp/Compiler COMPONENT ${LIBASSIMP-DEV_COMPONENT}) +INSTALL( TARGETS assimp + LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR} + RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR} + COMPONENT ${LIBASSIMP_COMPONENT}) +INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev) +INSTALL( FILES ${COMPILER_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp/Compiler COMPONENT assimp-dev) + +if(MSVC AND ASSIMP_INSTALL_PDB) + install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${ASSIMP_DEBUG_POSTFIX}.pdb + DESTINATION ${ASSIMP_LIB_INSTALL_DIR} + CONFIGURATIONS Debug + ) + install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp.pdb + DESTINATION ${ASSIMP_LIB_INSTALL_DIR} + CONFIGURATIONS RelWithDebInfo + ) +endif () diff --git a/src/3rdparty/assimp/code/COBLoader.cpp b/src/3rdparty/assimp/code/COBLoader.cpp index 5912a9555..49a45be7a 100644 --- a/src/3rdparty/assimp/code/COBLoader.cpp +++ b/src/3rdparty/assimp/code/COBLoader.cpp @@ -1045,9 +1045,9 @@ void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const v.y = reader.GetF4(); } - const size_t numfuck = reader.GetI4(); - msh.faces.reserve(numfuck); - for(size_t i = 0; i < numfuck; ++i) { + const size_t numf = reader.GetI4(); + msh.faces.reserve(numf); + for(size_t i = 0; i < numf; ++i) { // XXX backface culling flag is 0x10 in flags // hole? diff --git a/src/3rdparty/assimp/code/CSMLoader.cpp b/src/3rdparty/assimp/code/CSMLoader.cpp index b18a50a38..c92a3ac79 100644 --- a/src/3rdparty/assimp/code/CSMLoader.cpp +++ b/src/3rdparty/assimp/code/CSMLoader.cpp @@ -71,6 +71,7 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer CSMImporter::CSMImporter() +: noSkeletonMesh() {} // ------------------------------------------------------------------------------------------------ @@ -104,9 +105,9 @@ const aiImporterDesc* CSMImporter::GetInfo () const // ------------------------------------------------------------------------------------------------ // Setup configuration properties for the loader -void CSMImporter::SetupProperties(const Importer* /*pImp*/) +void CSMImporter::SetupProperties(const Importer* pImp) { - // nothing to be done for the moment + noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; } // ------------------------------------------------------------------------------------------------ @@ -289,7 +290,10 @@ void CSMImporter::InternReadFile( const std::string& pFile, // mark the scene as incomplete and run SkeletonMeshBuilder on it pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; - SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true); + + if (!noSkeletonMesh) { + SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true); + } } #endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER diff --git a/src/3rdparty/assimp/code/CSMLoader.h b/src/3rdparty/assimp/code/CSMLoader.h index a728abc32..624782f47 100644 --- a/src/3rdparty/assimp/code/CSMLoader.h +++ b/src/3rdparty/assimp/code/CSMLoader.h @@ -79,6 +79,9 @@ protected: IOSystem* pIOHandler); private: + + bool noSkeletonMesh; + }; // end of class CSMImporter } // end of namespace Assimp #endif // AI_AC3DIMPORTER_H_INC diff --git a/src/3rdparty/assimp/code/CalcTangentsProcess.cpp b/src/3rdparty/assimp/code/CalcTangentsProcess.cpp index e7e00369e..20ed3ea52 100644 --- a/src/3rdparty/assimp/code/CalcTangentsProcess.cpp +++ b/src/3rdparty/assimp/code/CalcTangentsProcess.cpp @@ -55,8 +55,9 @@ using namespace Assimp; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer CalcTangentsProcess::CalcTangentsProcess() -{ - this->configMaxAngle = AI_DEG_TO_RAD(45.f); +: configMaxAngle( AI_DEG_TO_RAD(45.f) ) +, configSourceUV( 0 ) { + // nothing to do here } // ------------------------------------------------------------------------------------------------ @@ -77,6 +78,8 @@ bool CalcTangentsProcess::IsActive( unsigned int pFlags) const // Executes the post processing step on the given imported data. void CalcTangentsProcess::SetupProperties(const Importer* pImp) { + ai_assert( NULL != pImp ); + // get the current value of the property configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f); configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f); @@ -89,14 +92,20 @@ void CalcTangentsProcess::SetupProperties(const Importer* pImp) // Executes the post processing step on the given imported data. void CalcTangentsProcess::Execute( aiScene* pScene) { - DefaultLogger::get()->debug("CalcTangentsProcess begin"); + ai_assert( NULL != pScene ); + + DefaultLogger::get()->debug("CalcTangentsProcess begin"); bool bHas = false; - for( unsigned int a = 0; a < pScene->mNumMeshes; a++) + for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) { if(ProcessMesh( pScene->mMeshes[a],a))bHas = true; + } - if (bHas)DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated"); - else DefaultLogger::get()->debug("CalcTangentsProcess finished"); + if ( bHas ) { + DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated"); + } else { + DefaultLogger::get()->debug("CalcTangentsProcess finished"); + } } // ------------------------------------------------------------------------------------------------ @@ -179,9 +188,14 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y; float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y; float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f; - - // tangent points in the direction where to positive X axis of the texture coords would point in model space - // bitangents points along the positive Y axis of the texture coords, respectively + // when t1, t2, t3 in same position in UV space, just use default UV direction. + if ( 0 == sx && 0 ==sy && 0 == tx && 0 == ty ) { + sx = 0.0; sy = 1.0; + tx = 1.0; ty = 0.0; + } + + // tangent points in the direction where to positive X axis of the texture coord's would point in model space + // bitangent's points along the positive Y axis of the texture coord's, respectively aiVector3D tangent, bitangent; tangent.x = (w.x * sy - v.x * ty) * dirCorrection; tangent.y = (w.y * sy - v.y * ty) * dirCorrection; @@ -191,8 +205,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) bitangent.z = (w.z * sx - v.z * tx) * dirCorrection; // store for every vertex of that face - for( unsigned int b = 0; b < face.mNumIndices; b++) - { + for( unsigned int b = 0; b < face.mNumIndices; ++b ) { unsigned int p = face.mIndices[b]; // project tangent and bitangent into the plane formed by the vertex' normal @@ -200,9 +213,22 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]); localTangent.Normalize(); localBitangent.Normalize(); - // and write it into the mesh. - meshTang[p] = localTangent; - meshBitang[p] = localBitangent; + // reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN. + bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z); + bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z); + if (invalid_tangent != invalid_bitangent) { + if (invalid_tangent) { + localTangent = meshNorm[p] ^ localBitangent; + localTangent.Normalize(); + } else { + localBitangent = localTangent ^ meshNorm[p]; + localBitangent.Normalize(); + } + } + + // and write it into the mesh. + meshTang[ p ] = localTangent; + meshBitang[ p ] = localBitangent; } } diff --git a/src/3rdparty/assimp/code/ColladaExporter.cpp b/src/3rdparty/assimp/code/ColladaExporter.cpp index 56d681119..2bf7deb72 100644 --- a/src/3rdparty/assimp/code/ColladaExporter.cpp +++ b/src/3rdparty/assimp/code/ColladaExporter.cpp @@ -44,6 +44,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER #include "ColladaExporter.h" +#include "Bitmap.h" +#include "fast_atof.h" +#include "SceneCombiner.h" + +#include <ctime> +#include <set> + using namespace Assimp; namespace Assimp @@ -53,11 +60,31 @@ namespace Assimp // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) { + std::string path = ""; + std::string file = pFile; + + // We need to test both types of folder separators because pIOSystem->getOsSeparator() is not reliable. + // Moreover, the path given by some applications is not even consistent with the OS specific type of separator. + const char* end_path = std::max(strrchr(pFile, '\\'), strrchr(pFile, '/')); + + if(end_path != NULL) { + path = std::string(pFile, end_path + 1 - pFile); + file = file.substr(end_path + 1 - pFile, file.npos); + + std::size_t pos = file.find_last_of('.'); + if(pos != file.npos) { + file = file.substr(0, pos); + } + } + // invoke the exporter - ColladaExporter iDoTheExportThing( pScene); + ColladaExporter iDoTheExportThing( pScene, pIOSystem, path, file); // we're still here - export successfully completed. Write result to the given IOSYstem boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output .dae file: " + std::string(pFile)); + } // XXX maybe use a small wrapper around IOStream that behaves like std::stringstream in order to avoid the extra copy. outfile->Write( iDoTheExportThing.mOutput.str().c_str(), static_cast<size_t>(iDoTheExportThing.mOutput.tellp()),1); @@ -68,12 +95,13 @@ void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, const aiScene* pS // ------------------------------------------------------------------------------------------------ // Constructor for a specific scene to export -ColladaExporter::ColladaExporter( const aiScene* pScene) +ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file) { // make sure that all formatting happens using the standard, C locale and not the user's current locale mOutput.imbue( std::locale("C") ); mScene = pScene; + mSceneOwned = false; // set up strings endstr = "\n"; @@ -83,6 +111,15 @@ ColladaExporter::ColladaExporter( const aiScene* pScene) } // ------------------------------------------------------------------------------------------------ +// Destructor +ColladaExporter::~ColladaExporter() +{ + if(mSceneOwned) { + delete mScene; + } +} + +// ------------------------------------------------------------------------------------------------ // Starts writing the contents void ColladaExporter::WriteFile() { @@ -92,17 +129,18 @@ void ColladaExporter::WriteFile() mOutput << "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">" << endstr; PushTag(); + WriteTextures(); WriteHeader(); - WriteMaterials(); + WriteMaterials(); WriteGeometryLibrary(); WriteSceneLibrary(); - // useless Collada bullshit at the end, just in case we haven't had enough indirections, yet. + // useless Collada fu at the end, just in case we haven't had enough indirections, yet. mOutput << startstr << "<scene>" << endstr; PushTag(); - mOutput << startstr << "<instance_visual_scene url=\"#myScene\" />" << endstr; + mOutput << startstr << "<instance_visual_scene url=\"#" + std::string(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr; PopTag(); mOutput << startstr << "</scene>" << endstr; PopTag(); @@ -113,24 +151,132 @@ void ColladaExporter::WriteFile() // Writes the asset header void ColladaExporter::WriteHeader() { - // Dummy stuff. Nobody actually cares for it anyways + static const float epsilon = 0.000001f; + static const aiQuaternion x_rot(aiMatrix3x3( + 0, -1, 0, + 1, 0, 0, + 0, 0, 1)); + static const aiQuaternion y_rot(aiMatrix3x3( + 1, 0, 0, + 0, 1, 0, + 0, 0, 1)); + static const aiQuaternion z_rot(aiMatrix3x3( + 1, 0, 0, + 0, 0, 1, + 0, -1, 0)); + + static const unsigned int date_nb_chars = 20; + char date_str[date_nb_chars]; + std::time_t date = std::time(NULL); + std::strftime(date_str, date_nb_chars, "%Y-%m-%dT%H:%M:%S", std::localtime(&date)); + + std::string scene_name = mScene->mRootNode->mName.C_Str(); + + aiVector3D scaling; + aiQuaternion rotation; + aiVector3D position; + mScene->mRootNode->mTransformation.Decompose(scaling, rotation, position); + + bool add_root_node = false; + + float scale = 1.0; + if(std::abs(scaling.x - scaling.y) <= epsilon && std::abs(scaling.x - scaling.z) <= epsilon && std::abs(scaling.y - scaling.z) <= epsilon) { + scale = (float) ((((double) scaling.x) + ((double) scaling.y) + ((double) scaling.z)) / 3.0); + } else { + add_root_node = true; + } + + std::string up_axis = "Y_UP"; + if(rotation.Equal(x_rot, epsilon)) { + up_axis = "X_UP"; + } else if(rotation.Equal(y_rot, epsilon)) { + up_axis = "Y_UP"; + } else if(rotation.Equal(z_rot, epsilon)) { + up_axis = "Z_UP"; + } else { + add_root_node = true; + } + + if(! position.Equal(aiVector3D(0, 0, 0))) { + add_root_node = true; + } + + if(mScene->mRootNode->mNumChildren == 0) { + add_root_node = true; + } + + if(add_root_node) { + aiScene* scene; + SceneCombiner::CopyScene(&scene, mScene); + + aiNode* root = new aiNode("Scene"); + + root->mNumChildren = 1; + root->mChildren = new aiNode*[root->mNumChildren]; + + root->mChildren[0] = scene->mRootNode; + scene->mRootNode->mParent = root; + scene->mRootNode = root; + + mScene = scene; + mSceneOwned = true; + + up_axis = "Y_UP"; + scale = 1.0; + } + mOutput << startstr << "<asset>" << endstr; PushTag(); mOutput << startstr << "<contributor>" << endstr; PushTag(); - mOutput << startstr << "<author>Someone</author>" << endstr; + mOutput << startstr << "<author>Assimp</author>" << endstr; mOutput << startstr << "<authoring_tool>Assimp Collada Exporter</authoring_tool>" << endstr; PopTag(); mOutput << startstr << "</contributor>" << endstr; - mOutput << startstr << "<created>2000-01-01T23:59:59</created>" << endstr; - mOutput << startstr << "<modified>2000-01-01T23:59:59</modified>" << endstr; - mOutput << startstr << "<unit name=\"centimeter\" meter=\"0.01\" />" << endstr; - mOutput << startstr << "<up_axis>Y_UP</up_axis>" << endstr; + mOutput << startstr << "<created>" << date_str << "</created>" << endstr; + mOutput << startstr << "<modified>" << date_str << "</modified>" << endstr; + mOutput << startstr << "<unit name=\"meter\" meter=\"" << scale << "\" />" << endstr; + mOutput << startstr << "<up_axis>" << up_axis << "</up_axis>" << endstr; PopTag(); mOutput << startstr << "</asset>" << endstr; } // ------------------------------------------------------------------------------------------------ +// Write the embedded textures +void ColladaExporter::WriteTextures() { + static const unsigned int buffer_size = 1024; + char str[buffer_size]; + + if(mScene->HasTextures()) { + for(unsigned int i = 0; i < mScene->mNumTextures; i++) { + // It would be great to be able to create a directory in portable standard C++, but it's not the case, + // so we just write the textures in the current directory. + + aiTexture* texture = mScene->mTextures[i]; + + ASSIMP_itoa10(str, buffer_size, i + 1); + + std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint); + + boost::scoped_ptr<IOStream> outfile(mIOSystem->Open(mPath + name, "wb")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output texture file: " + mPath + name); + } + + if(texture->mHeight == 0) { + outfile->Write((void*) texture->pcData, texture->mWidth, 1); + } else { + Bitmap::Save(texture, outfile.get()); + } + + outfile->Flush(); + + textures.insert(std::make_pair(i, name)); + } + } +} + +// ------------------------------------------------------------------------------------------------ // Reads a single surface entry from the given material keys void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex) { @@ -139,12 +285,39 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* aiString texfile; unsigned int uvChannel = 0; pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel); - poSurface.texture = texfile.C_Str(); + + std::string index_str(texfile.C_Str()); + + if(index_str.size() != 0 && index_str[0] == '*') + { + unsigned int index; + + index_str = index_str.substr(1, std::string::npos); + + try { + index = (unsigned int) strtoul10_64(index_str.c_str()); + } catch(std::exception& error) { + throw DeadlyExportError(error.what()); + } + + std::map<unsigned int, std::string>::const_iterator name = textures.find(index); + + if(name != textures.end()) { + poSurface.texture = name->second; + } else { + throw DeadlyExportError("could not find embedded texture at index " + index_str); + } + } else + { + poSurface.texture = texfile.C_Str(); + } + poSurface.channel = uvChannel; + poSurface.exist = true; } else { if( pKey ) - pSrcMat->Get( pKey, pType, pIndex, poSurface.color); + poSurface.exist = pSrcMat->Get( pKey, pType, pIndex, poSurface.color) == aiReturn_SUCCESS; } } @@ -174,17 +347,19 @@ void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::strin // Writes a color-or-texture entry into an effect definition void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName) { - mOutput << startstr << "<" << pTypeName << ">" << endstr; - PushTag(); - if( pSurface.texture.empty() ) - { - mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr; - } else - { - mOutput << startstr << "<texture texture=\"" << pImageName << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr; + if(pSurface.exist) { + mOutput << startstr << "<" << pTypeName << ">" << endstr; + PushTag(); + if( pSurface.texture.empty() ) + { + mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr; + } else + { + mOutput << startstr << "<texture texture=\"" << pImageName << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr; + } + PopTag(); + mOutput << startstr << "</" << pTypeName << ">" << endstr; } - PopTag(); - mOutput << startstr << "</" << pTypeName << ">" << endstr; } // ------------------------------------------------------------------------------------------------ @@ -217,11 +392,26 @@ void ColladaExporter::WriteTextureParamEntry( const Surface& pSurface, const std } // ------------------------------------------------------------------------------------------------ +// Writes a scalar property +void ColladaExporter::WriteFloatEntry( const Property& pProperty, const std::string& pTypeName) +{ + if(pProperty.exist) { + mOutput << startstr << "<" << pTypeName << ">" << endstr; + PushTag(); + mOutput << startstr << "<float sid=\"" << pTypeName << "\">" << pProperty.value << "</float>" << endstr; + PopTag(); + mOutput << startstr << "</" << pTypeName << ">" << endstr; + } +} + +// ------------------------------------------------------------------------------------------------ // Writes the material setup void ColladaExporter::WriteMaterials() { materials.resize( mScene->mNumMaterials); + std::set<std::string> material_names; + /// collect all materials from the scene size_t numTextures = 0; for( size_t a = 0; a < mScene->mNumMaterials; ++a ) @@ -232,9 +422,27 @@ void ColladaExporter::WriteMaterials() if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS ) name = "mat"; materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str(); - for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) - if( !isalnum( *it) ) + for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) { + // isalnum on MSVC asserts for code points in [0,255]. Thus prevent unwanted promotion + // of char to signed int and take the unsigned char value. + if( !isalnum( static_cast<uint8_t>(*it) ) ) { *it = '_'; + } + } + + aiShadingMode shading; + materials[a].shading_model = "phong"; + if(mat->Get( AI_MATKEY_SHADING_MODEL, shading) == aiReturn_SUCCESS) { + if(shading == aiShadingMode_Phong) { + materials[a].shading_model = "phong"; + } else if(shading == aiShadingMode_Blinn) { + materials[a].shading_model = "blinn"; + } else if(shading == aiShadingMode_NoShading) { + materials[a].shading_model = "constant"; + } else if(shading == aiShadingMode_Gouraud) { + materials[a].shading_model = "lambert"; + } + } ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT); if( !materials[a].ambient.texture.empty() ) numTextures++; @@ -246,10 +454,15 @@ void ColladaExporter::WriteMaterials() if( !materials[a].emissive.texture.empty() ) numTextures++; ReadMaterialSurface( materials[a].reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE); if( !materials[a].reflective.texture.empty() ) numTextures++; + ReadMaterialSurface( materials[a].transparent, mat, aiTextureType_OPACITY, AI_MATKEY_COLOR_TRANSPARENT); + if( !materials[a].transparent.texture.empty() ) numTextures++; ReadMaterialSurface( materials[a].normal, mat, aiTextureType_NORMALS, NULL, 0, 0); if( !materials[a].normal.texture.empty() ) numTextures++; - mat->Get( AI_MATKEY_SHININESS, materials[a].shininess); + materials[a].shininess.exist = mat->Get( AI_MATKEY_SHININESS, materials[a].shininess.value) == aiReturn_SUCCESS; + materials[a].transparency.exist = mat->Get( AI_MATKEY_OPACITY, materials[a].transparency.value) == aiReturn_SUCCESS; + materials[a].transparency.value = 1 - materials[a].transparency.value; + materials[a].index_refraction.exist = mat->Get( AI_MATKEY_REFRACTI, materials[a].index_refraction.value) == aiReturn_SUCCESS; } // output textures if present @@ -263,8 +476,9 @@ void ColladaExporter::WriteMaterials() WriteImageEntry( mat.ambient, mat.name + "-ambient-image"); WriteImageEntry( mat.diffuse, mat.name + "-diffuse-image"); WriteImageEntry( mat.specular, mat.name + "-specular-image"); - WriteImageEntry( mat.emissive, mat.name + "-emissive-image"); + WriteImageEntry( mat.emissive, mat.name + "-emission-image"); WriteImageEntry( mat.reflective, mat.name + "-reflective-image"); + WriteImageEntry( mat.transparent, mat.name + "-transparent-image"); WriteImageEntry( mat.normal, mat.name + "-normal-image"); } PopTag(); @@ -286,37 +500,35 @@ void ColladaExporter::WriteMaterials() PushTag(); // write sampler- and surface params for the texture entries - WriteTextureParamEntry( mat.emissive, "emissive", mat.name); + WriteTextureParamEntry( mat.emissive, "emission", mat.name); WriteTextureParamEntry( mat.ambient, "ambient", mat.name); WriteTextureParamEntry( mat.diffuse, "diffuse", mat.name); WriteTextureParamEntry( mat.specular, "specular", mat.name); WriteTextureParamEntry( mat.reflective, "reflective", mat.name); + WriteTextureParamEntry( mat.transparent, "transparent", mat.name); + WriteTextureParamEntry( mat.normal, "normal", mat.name); mOutput << startstr << "<technique sid=\"standard\">" << endstr; PushTag(); - mOutput << startstr << "<phong>" << endstr; + mOutput << startstr << "<" << mat.shading_model << ">" << endstr; PushTag(); - WriteTextureColorEntry( mat.emissive, "emission", mat.name + "-emissive-sampler"); + WriteTextureColorEntry( mat.emissive, "emission", mat.name + "-emission-sampler"); WriteTextureColorEntry( mat.ambient, "ambient", mat.name + "-ambient-sampler"); WriteTextureColorEntry( mat.diffuse, "diffuse", mat.name + "-diffuse-sampler"); WriteTextureColorEntry( mat.specular, "specular", mat.name + "-specular-sampler"); - - mOutput << startstr << "<shininess>" << endstr; - PushTag(); - mOutput << startstr << "<float sid=\"shininess\">" << mat.shininess << "</float>" << endstr; - PopTag(); - mOutput << startstr << "</shininess>" << endstr; - + WriteFloatEntry(mat.shininess, "shininess"); WriteTextureColorEntry( mat.reflective, "reflective", mat.name + "-reflective-sampler"); + WriteTextureColorEntry( mat.transparent, "transparent", mat.name + "-transparent-sampler"); + WriteFloatEntry(mat.transparency, "transparency"); + WriteFloatEntry(mat.index_refraction, "index_of_refraction"); - // deactivated because the Collada spec PHONG model does not allow other textures. - // if( !mat.normal.texture.empty() ) - // WriteTextureColorEntry( mat.normal, "bump", mat.name + "-normal-sampler"); - + if(! mat.normal.texture.empty()) { + WriteTextureColorEntry( mat.normal, "bump", mat.name + "-normal-sampler"); + } PopTag(); - mOutput << startstr << "</phong>" << endstr; + mOutput << startstr << "</" << mat.shading_model << ">" << endstr; PopTag(); mOutput << startstr << "</technique>" << endstr; PopTag(); @@ -495,7 +707,7 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy mOutput << "</float_array>" << endstr; PopTag(); - // the usual Collada bullshit. Let's bloat it even more! + // the usual Collada fun. Let's bloat it even more! mOutput << startstr << "<technique_common>" << endstr; PushTag(); mOutput << startstr << "<accessor count=\"" << pElementCount << "\" offset=\"0\" source=\"#" << arrayId << "\" stride=\"" << floatsPerElement << "\">" << endstr; @@ -539,13 +751,16 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy // Writes the scene library void ColladaExporter::WriteSceneLibrary() { + std::string scene_name = mScene->mRootNode->mName.C_Str(); + mOutput << startstr << "<library_visual_scenes>" << endstr; PushTag(); - mOutput << startstr << "<visual_scene id=\"myScene\" name=\"myScene\">" << endstr; + mOutput << startstr << "<visual_scene id=\"" + scene_name + "\" name=\"" + scene_name + "\">" << endstr; PushTag(); // start recursive write at the root node - WriteNode( mScene->mRootNode); + for( size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a ) + WriteNode( mScene->mRootNode->mChildren[a]); PopTag(); mOutput << startstr << "</visual_scene>" << endstr; @@ -574,22 +789,22 @@ void ColladaExporter::WriteNode( const aiNode* pNode) for( size_t a = 0; a < pNode->mNumMeshes; ++a ) { const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]]; - // do not instanciate mesh if empty. I wonder how this could happen - if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 ) - continue; + // do not instanciate mesh if empty. I wonder how this could happen + if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 ) + continue; mOutput << startstr << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << endstr; PushTag(); - mOutput << startstr << "<bind_material>" << endstr; - PushTag(); - mOutput << startstr << "<technique_common>" << endstr; - PushTag(); - mOutput << startstr << "<instance_material symbol=\"theresonlyone\" target=\"#" << materials[mesh->mMaterialIndex].name << "\" />" << endstr; + mOutput << startstr << "<bind_material>" << endstr; + PushTag(); + mOutput << startstr << "<technique_common>" << endstr; + PushTag(); + mOutput << startstr << "<instance_material symbol=\"theresonlyone\" target=\"#" << materials[mesh->mMaterialIndex].name << "\" />" << endstr; PopTag(); - mOutput << startstr << "</technique_common>" << endstr; - PopTag(); - mOutput << startstr << "</bind_material>" << endstr; - PopTag(); + mOutput << startstr << "</technique_common>" << endstr; + PopTag(); + mOutput << startstr << "</bind_material>" << endstr; + PopTag(); mOutput << startstr << "</instance_geometry>" << endstr; } diff --git a/src/3rdparty/assimp/code/ColladaExporter.h b/src/3rdparty/assimp/code/ColladaExporter.h index 53ae702b7..acd1bad4c 100644 --- a/src/3rdparty/assimp/code/ColladaExporter.h +++ b/src/3rdparty/assimp/code/ColladaExporter.h @@ -59,7 +59,10 @@ class ColladaExporter { public: /// Constructor for a specific scene to export - ColladaExporter( const aiScene* pScene); + ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file); + + /// Destructor + virtual ~ColladaExporter(); protected: /// Starts writing the contents @@ -68,8 +71,11 @@ protected: /// Writes the asset header void WriteHeader(); - /// Writes the material setup - void WriteMaterials(); + /// Writes the embedded textures + void WriteTextures(); + + /// Writes the material setup + void WriteMaterials(); /// Writes the geometry library void WriteGeometryLibrary(); @@ -101,8 +107,18 @@ public: std::stringstream mOutput; protected: + /// The IOSystem for output + IOSystem* mIOSystem; + + /// Path of the directory where the scene will be exported + const std::string mPath; + + /// Name of the file (without extension) where the scene will be exported + const std::string mFile; + /// The scene to be written const aiScene* mScene; + bool mSceneOwned; /// current line start string, contains the current indentation for simple stream insertion std::string startstr; @@ -112,24 +128,35 @@ protected: // pair of color and texture - texture precedences color struct Surface { + bool exist; aiColor4D color; std::string texture; size_t channel; - Surface() { channel = 0; } + Surface() { exist = false; channel = 0; } + }; + + struct Property + { + bool exist; + float value; + Property() { exist = false; } }; // summarize a material in an convinient way. struct Material { std::string name; - Surface ambient, diffuse, specular, emissive, reflective, normal; - float shininess; /// specular exponent + std::string shading_model; + Surface ambient, diffuse, specular, emissive, reflective, transparent, normal; + Property shininess, transparency, index_refraction; - Material() { shininess = 16.0f; } + Material() {} }; std::vector<Material> materials; + std::map<unsigned int, std::string> textures; + protected: /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions /// Reads a single surface entry from the given material keys @@ -140,6 +167,8 @@ protected: void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName); /// Writes a color-or-texture entry into an effect definition void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName); + /// Writes a scalar property + void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName); }; } diff --git a/src/3rdparty/assimp/code/ColladaHelper.h b/src/3rdparty/assimp/code/ColladaHelper.h index c713e6ace..0e087bd21 100644 --- a/src/3rdparty/assimp/code/ColladaHelper.h +++ b/src/3rdparty/assimp/code/ColladaHelper.h @@ -119,6 +119,7 @@ struct Camera }; #define aiLightSource_AMBIENT 0xdeaddead +#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f /** A collada light source. */ struct Light @@ -129,8 +130,8 @@ struct Light , mAttQuadratic (0.f) , mFalloffAngle (180.f) , mFalloffExponent (0.f) - , mPenumbraAngle (10e10f) - , mOuterAngle (10e10f) + , mPenumbraAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET) + , mOuterAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET) , mIntensity (1.f) {} @@ -320,6 +321,8 @@ struct Mesh for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i) mNumUVComponents[i] = 2; } + + std::string mName; // just to check if there's some sophisticated addressing involved... // which we don't support, and therefore should warn about. diff --git a/src/3rdparty/assimp/code/ColladaLoader.cpp b/src/3rdparty/assimp/code/ColladaLoader.cpp index bf807b8b6..86406aad9 100644 --- a/src/3rdparty/assimp/code/ColladaLoader.cpp +++ b/src/3rdparty/assimp/code/ColladaLoader.cpp @@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** @file Implementation of the Collada loader */ #include "AssimpPCH.h" -#ifndef ASSIMP_BUILD_NO_DAE_IMPORTER +#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER #include "../include/assimp/anim.h" #include "ColladaLoader.h" @@ -73,6 +73,7 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer ColladaLoader::ColladaLoader() +: noSkeletonMesh(), ignoreUpDirection(false) {} // ------------------------------------------------------------------------------------------------ @@ -104,6 +105,14 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo } // ------------------------------------------------------------------------------------------------ +void ColladaLoader::SetupProperties(const Importer* pImp) +{ + noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; + ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION,0) != 0; +} + + +// ------------------------------------------------------------------------------------------------ // Get file extension list const aiImporterDesc* ColladaLoader::GetInfo () const { @@ -147,20 +156,26 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I // ... then fill the materials with the now adjusted settings FillMaterials(parser, pScene); - // Convert to Y_UP, if different orientation - if( parser.mUpDirection == ColladaParser::UP_X) - pScene->mRootNode->mTransformation *= aiMatrix4x4( - 0, -1, 0, 0, - 1, 0, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - else if( parser.mUpDirection == ColladaParser::UP_Z) - pScene->mRootNode->mTransformation *= aiMatrix4x4( - 1, 0, 0, 0, - 0, 0, 1, 0, - 0, -1, 0, 0, - 0, 0, 0, 1); - + // Apply unitsize scale calculation + pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0, + 0, parser.mUnitSize, 0, 0, + 0, 0, parser.mUnitSize, 0, + 0, 0, 0, 1); + if( !ignoreUpDirection ) { + // Convert to Y_UP, if different orientation + if( parser.mUpDirection == ColladaParser::UP_X) + pScene->mRootNode->mTransformation *= aiMatrix4x4( + 0, -1, 0, 0, + 1, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + else if( parser.mUpDirection == ColladaParser::UP_Z) + pScene->mRootNode->mTransformation *= aiMatrix4x4( + 1, 0, 0, 0, + 0, 0, 1, 0, + 0, -1, 0, 0, + 0, 0, 0, 1); + } // store all meshes StoreSceneMeshes( pScene); @@ -180,7 +195,9 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I // If no meshes have been loaded, it's probably just an animated skeleton. if (!pScene->mNumMeshes) { - SkeletonMeshBuilder hero(pScene); + if (!noSkeletonMesh) { + SkeletonMeshBuilder hero(pScene); + } pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; } } @@ -315,11 +332,11 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll out->mAngleInnerCone = AI_DEG_TO_RAD( srcLight->mFalloffAngle ); - // ... some extension magic. FUCKING COLLADA. - if (srcLight->mOuterAngle == 10e10f) + // ... some extension magic. + if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f)) { - // ... some deprecation magic. FUCKING FCOLLADA. - if (srcLight->mPenumbraAngle == 10e10f) + // ... some deprecation magic. + if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f)) { // Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess .... // epsilon chosen to be 0.1 @@ -372,7 +389,7 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col out->mClipPlaneNear = srcCamera->mZNear; // ... but for the rest some values are optional - // and we need to compute the others in any combination. FUCKING COLLADA. + // and we need to compute the others in any combination. if (srcCamera->mAspect != 10e10f) out->mAspect = srcCamera->mAspect; @@ -456,7 +473,7 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll } else { - DefaultLogger::get()->warn( boost::str( boost::format( "Collada: No material specified for subgroup \"%s\" in geometry \"%s\".") % submesh.mMaterial % mid.mMeshOrController)); + DefaultLogger::get()->warn( boost::str( boost::format( "Collada: No material specified for subgroup <%s> in geometry <%s>.") % submesh.mMaterial % mid.mMeshOrController)); if( !mid.mMaterials.empty() ) meshMaterial = mid.mMaterials.begin()->second.mMatName; } @@ -504,7 +521,11 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll // assign the material index dstMesh->mMaterialIndex = matIdx; - } + if(dstMesh->mName.length == 0) + { + dstMesh->mName = mid.mMeshOrController; + } + } } } @@ -523,6 +544,8 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace) { aiMesh* dstMesh = new aiMesh; + + dstMesh->mName = pSrcMesh->mName; // count the vertices addressed by its faces const size_t numVertices = std::accumulate( pSrcMesh->mFaceSize.begin() + pStartFace, @@ -534,7 +557,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: std::copy( pSrcMesh->mPositions.begin() + pStartVertex, pSrcMesh->mPositions.begin() + pStartVertex + numVertices, dstMesh->mVertices); - // normals, if given. HACK: (thom) Due to the fucking Collada spec we never + // normals, if given. HACK: (thom) Due to the glorious Collada spec we never // know if we have the same number of normals as there are positions. So we // also ignore any vertex attribute if it has a different count if( pSrcMesh->mNormals.size() >= pStartVertex + numVertices) @@ -625,7 +648,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada:: throw DeadlyImportError( "Data type mismatch while resolving mesh joints"); // sanity check: we rely on the vertex weights always coming as pairs of BoneIndex-WeightIndex if( pSrcController->mWeightInputJoints.mOffset != 0 || pSrcController->mWeightInputWeights.mOffset != 1) - throw DeadlyImportError( "Unsupported vertex_weight adresssing scheme. Fucking collada spec."); + throw DeadlyImportError( "Unsupported vertex_weight addressing scheme. "); // create containers to collect the weights for each bone size_t numBones = jointNames.mStrings.size(); @@ -956,7 +979,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars else if( subElement == "Z") entry.mSubElement = 2; else - DefaultLogger::get()->warn( boost::str( boost::format( "Unknown anim subelement \"%s\". Ignoring") % subElement)); + DefaultLogger::get()->warn( boost::str( boost::format( "Unknown anim subelement <%s>. Ignoring") % subElement)); } else { // no subelement following, transformId is remaining string @@ -1434,13 +1457,16 @@ void ColladaLoader::ConvertPath (aiString& ss) ss.data[ss.length] = 0; } - // find and convert all %xyz special chars + // find and convert all %xy special chars char* out = ss.data; for( const char* it = ss.data; it != ss.data + ss.length; /**/ ) { - if( *it == '%' ) + if( *it == '%' && (it + 3) < ss.data + ss.length ) { - size_t nbr = strtoul16( ++it, &it); + // separate the number to avoid dragging in chars from behind into the parsing + char mychar[3] = { it[1], it[2], 0 }; + size_t nbr = strtoul16( mychar); + it += 3; *out++ = (char)(nbr & 0xFF); } else { diff --git a/src/3rdparty/assimp/code/ColladaLoader.h b/src/3rdparty/assimp/code/ColladaLoader.h index c52774114..4f22a51cd 100644 --- a/src/3rdparty/assimp/code/ColladaLoader.h +++ b/src/3rdparty/assimp/code/ColladaLoader.h @@ -94,6 +94,8 @@ protected: */ const aiImporterDesc* GetInfo () const; + void SetupProperties(const Importer* pImp); + /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details */ @@ -230,6 +232,9 @@ protected: /** Accumulated animations for the target scene */ std::vector<aiAnimation*> mAnims; + + bool noSkeletonMesh; + bool ignoreUpDirection; }; } // end of namespace Assimp diff --git a/src/3rdparty/assimp/code/ColladaParser.cpp b/src/3rdparty/assimp/code/ColladaParser.cpp index 90b4824b4..a230b64e7 100644 --- a/src/3rdparty/assimp/code/ColladaParser.cpp +++ b/src/3rdparty/assimp/code/ColladaParser.cpp @@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AssimpPCH.h" -#ifndef ASSIMP_BUILD_NO_DAE_IMPORTER +#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER #include "ColladaParser.h" #include "fast_atof.h" @@ -140,7 +140,7 @@ void ColladaParser::ReadContents() ReadStructure(); } else { - DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element \"%s\".") % mReader->getNodeName())); + DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element <%s>.") % mReader->getNodeName())); SkipElement(); } } else @@ -240,7 +240,7 @@ void ColladaParser::ReadAssetInfo() else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "asset") != 0) - ThrowException( "Expected end of \"asset\" element."); + ThrowException( "Expected end of <asset> element."); break; } @@ -271,7 +271,7 @@ void ColladaParser::ReadAnimationLibrary() else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "library_animations") != 0) - ThrowException( "Expected end of \"library_animations\" element."); + ThrowException( "Expected end of <library_animations> element."); break; } @@ -362,7 +362,7 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent) else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "animation") != 0) - ThrowException( "Expected end of \"animation\" element."); + ThrowException( "Expected end of <animation> element."); break; } @@ -425,7 +425,7 @@ void ColladaParser::ReadAnimationSampler( Collada::AnimationChannel& pChannel) else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "sampler") != 0) - ThrowException( "Expected end of \"sampler\" element."); + ThrowException( "Expected end of <sampler> element."); break; } @@ -463,7 +463,7 @@ void ColladaParser::ReadControllerLibrary() else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "library_controllers") != 0) - ThrowException( "Expected end of \"library_controllers\" element."); + ThrowException( "Expected end of <library_controllers> element."); break; } @@ -487,7 +487,7 @@ void ColladaParser::ReadController( Collada::Controller& pController) else if( IsElement( "skin")) { // read the mesh it refers to. According to the spec this could also be another - // controller, but I refuse to implement every bullshit idea they've come up with + // controller, but I refuse to implement every single idea they've come up with int sourceIndex = GetAttribute( "source"); pController.mMeshId = mReader->getAttributeValue( sourceIndex) + 1; } @@ -531,7 +531,7 @@ void ColladaParser::ReadController( Collada::Controller& pController) if( strcmp( mReader->getNodeName(), "controller") == 0) break; else if( strcmp( mReader->getNodeName(), "skin") != 0) - ThrowException( "Expected end of \"controller\" element."); + ThrowException( "Expected end of <controller> element."); } } } @@ -554,7 +554,7 @@ void ColladaParser::ReadControllerJoints( Collada::Controller& pController) // local URLS always start with a '#'. We don't support global URLs if( attrSource[0] != '#') - ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\"") % attrSource)); + ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of <joints> data <input> element") % attrSource)); attrSource++; // parse source URL to corresponding source @@ -563,7 +563,7 @@ void ColladaParser::ReadControllerJoints( Collada::Controller& pController) else if( strcmp( attrSemantic, "INV_BIND_MATRIX") == 0) pController.mJointOffsetMatrixSource = attrSource; else - ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in joint data") % attrSemantic)); + ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in <joints> data <input> element") % attrSemantic)); // skip inner data, if present if( !mReader->isEmptyElement()) @@ -578,7 +578,7 @@ void ColladaParser::ReadControllerJoints( Collada::Controller& pController) else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "joints") != 0) - ThrowException( "Expected end of \"joints\" element."); + ThrowException( "Expected end of <joints> element."); break; } @@ -599,7 +599,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { // Input channels for weight data. Two possible semantics: "JOINT" and "WEIGHT" - if( IsElement( "input")) + if( IsElement( "input") && vertexCount > 0 ) { InputChannel channel; @@ -613,7 +613,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) // local URLS always start with a '#'. We don't support global URLs if( attrSource[0] != '#') - ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\"") % attrSource)); + ThrowException( boost::str( boost::format( "Unsupported URL format in \"%s\" in source attribute of <vertex_weights> data <input> element") % attrSource)); channel.mAccessor = attrSource + 1; // parse source URL to corresponding source @@ -622,13 +622,13 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) else if( strcmp( attrSemantic, "WEIGHT") == 0) pController.mWeightInputWeights = channel; else - ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in vertex_weight data") % attrSemantic)); + ThrowException( boost::str( boost::format( "Unknown semantic \"%s\" in <vertex_weights> data <input> element") % attrSemantic)); // skip inner data, if present if( !mReader->isEmptyElement()) SkipElement(); } - else if( IsElement( "vcount")) + else if( IsElement( "vcount") && vertexCount > 0 ) { // read weight count per vertex const char* text = GetTextContent(); @@ -636,7 +636,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) for( std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) { if( *text == 0) - ThrowException( "Out of data while reading vcount"); + ThrowException( "Out of data while reading <vcount>"); *it = strtoul10( text, &text); numWeights += *it; @@ -648,7 +648,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) // reserve weight count pController.mWeights.resize( numWeights); } - else if( IsElement( "v")) + else if( IsElement( "v") && vertexCount > 0 ) { // read JointIndex - WeightIndex pairs const char* text = GetTextContent(); @@ -656,11 +656,11 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) for( std::vector< std::pair<size_t, size_t> >::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) { if( *text == 0) - ThrowException( "Out of data while reading vertex_weights"); + ThrowException( "Out of data while reading <vertex_weights>"); it->first = strtoul10( text, &text); SkipSpacesAndLineEnd( &text); if( *text == 0) - ThrowException( "Out of data while reading vertex_weights"); + ThrowException( "Out of data while reading <vertex_weights>"); it->second = strtoul10( text, &text); SkipSpacesAndLineEnd( &text); } @@ -676,7 +676,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "vertex_weights") != 0) - ThrowException( "Expected end of \"vertex_weights\" element."); + ThrowException( "Expected end of <vertex_weights> element."); break; } @@ -712,7 +712,7 @@ void ColladaParser::ReadImageLibrary() } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "library_images") != 0) - ThrowException( "Expected end of \"library_images\" element."); + ThrowException( "Expected end of <library_images> element."); break; } @@ -838,7 +838,7 @@ void ColladaParser::ReadMaterialLibrary() else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "library_materials") != 0) - ThrowException( "Expected end of \"library_materials\" element."); + ThrowException( "Expected end of <library_materials> element."); break; } @@ -872,7 +872,7 @@ void ColladaParser::ReadLightLibrary() } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "library_lights") != 0) - ThrowException( "Expected end of \"library_lights\" element."); + ThrowException( "Expected end of <library_lights> element."); break; } @@ -911,7 +911,7 @@ void ColladaParser::ReadCameraLibrary() } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "library_cameras") != 0) - ThrowException( "Expected end of \"library_cameras\" element."); + ThrowException( "Expected end of <library_cameras> element."); break; } @@ -947,7 +947,7 @@ void ColladaParser::ReadMaterial( Collada::Material& pMaterial) } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "material") != 0) - ThrowException( "Expected end of \"material\" element."); + ThrowException( "Expected end of <material> element."); break; } @@ -1097,9 +1097,6 @@ void ColladaParser::ReadEffectLibrary() if( IsElement( "effect")) { // read ID. Do I have to repeat my ranting about "optional" attributes? - // Alex: .... no, not necessary. Please shut up and leave more space for - // me to complain about the fucking Collada spec with its fucking - // 'optional' attributes ... int attrID = GetAttribute( "id"); std::string id = mReader->getAttributeValue( attrID); @@ -1115,7 +1112,7 @@ void ColladaParser::ReadEffectLibrary() } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "library_effects") != 0) - ThrowException( "Expected end of \"library_effects\" element."); + ThrowException( "Expected end of <library_effects> element."); break; } @@ -1139,7 +1136,7 @@ void ColladaParser::ReadEffect( Collada::Effect& pEffect) else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "effect") != 0) - ThrowException( "Expected end of \"effect\" element."); + ThrowException( "Expected end of <effect> element."); break; } @@ -1369,9 +1366,11 @@ void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler) int attrTex = GetAttribute( "texture"); pSampler.mName = mReader->getAttributeValue( attrTex); - // get name of UV source channel - attrTex = GetAttribute( "texcoord"); - pSampler.mUVChannel = mReader->getAttributeValue( attrTex); + // get name of UV source channel. Specification demands it to be there, but some exporters + // don't write it. It will be the default UV channel in case it's missing. + attrTex = TestAttribute( "texcoord"); + if( attrTex >= 0 ) + pSampler.mUVChannel = mReader->getAttributeValue( attrTex); //SkipElement(); } else if( IsElement( "technique")) @@ -1493,6 +1492,13 @@ void ColladaParser::ReadGeometryLibrary() // create a mesh and store it in the library under its ID Mesh* mesh = new Mesh; mMeshLibrary[id] = mesh; + + // read the mesh name if it exists + const int nameIndex = TestAttribute("name"); + if(nameIndex != -1) + { + mesh->mName = mReader->getAttributeValue(nameIndex); + } // read on from there ReadGeometry( mesh); @@ -1505,7 +1511,7 @@ void ColladaParser::ReadGeometryLibrary() else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "library_geometries") != 0) - ThrowException( "Expected end of \"library_geometries\" element."); + ThrowException( "Expected end of <library_geometries> element."); break; } @@ -1536,7 +1542,7 @@ void ColladaParser::ReadGeometry( Collada::Mesh* pMesh) else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "geometry") != 0) - ThrowException( "Expected end of \"geometry\" element."); + ThrowException( "Expected end of <geometry> element."); break; } @@ -1588,7 +1594,7 @@ void ColladaParser::ReadMesh( Mesh* pMesh) } else { // everything else should be punished - ThrowException( "Expected end of \"mesh\" element."); + ThrowException( "Expected end of <mesh> element."); } } } @@ -1611,7 +1617,7 @@ void ColladaParser::ReadSource() } else if( IsElement( "technique_common")) { - // I don't fucking care for your profiles bullshit + // I don't care for your profiles } else if( IsElement( "accessor")) { @@ -1635,7 +1641,7 @@ void ColladaParser::ReadSource() } else { // everything else should be punished - ThrowException( "Expected end of \"source\" element."); + ThrowException( "Expected end of <source> element."); } } } @@ -1713,7 +1719,7 @@ void ColladaParser::ReadAccessor( const std::string& pID) int attrSource = GetAttribute( "source"); const char* source = mReader->getAttributeValue( attrSource); if( source[0] != '#') - ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\".") % source)); + ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of <accessor> element.") % source)); int attrCount = GetAttribute( "count"); unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount); int attrOffset = TestAttribute( "offset"); @@ -1795,14 +1801,13 @@ void ColladaParser::ReadAccessor( const std::string& pID) SkipElement(); } else { - ThrowException( "Unexpected sub element in tag \"accessor\"."); + ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <accessor>") % mReader->getNodeName())); } } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "accessor") != 0) - ThrowException( "Expected end of \"accessor\" element."); - + ThrowException( "Expected end of <accessor> element."); break; } } @@ -1826,13 +1831,13 @@ void ColladaParser::ReadVertexData( Mesh* pMesh) ReadInputChannel( pMesh->mPerVertexData); } else { - ThrowException( "Unexpected sub element in tag \"vertices\"."); + ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <vertices>") % mReader->getNodeName())); } } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( strcmp( mReader->getNodeName(), "vertices") != 0) - ThrowException( "Expected end of \"vertices\" element."); + ThrowException( "Expected end of <vertices> element."); break; } @@ -1899,7 +1904,7 @@ void ColladaParser::ReadIndexData( Mesh* pMesh) for( unsigned int a = 0; a < numPrimitives; a++) { if( *content == 0) - ThrowException( "Expected more values while reading vcount contents."); + ThrowException( "Expected more values while reading <vcount> contents."); // read a number vcount.push_back( (size_t) strtoul10( content, &content)); // skip whitespace after it @@ -1919,13 +1924,13 @@ void ColladaParser::ReadIndexData( Mesh* pMesh) } } else { - ThrowException( "Unexpected sub element in tag \"vertices\"."); + ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <%s>") % mReader->getNodeName() % elementName)); } } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { if( mReader->getNodeName() != elementName) - ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % elementName)); + ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % elementName)); break; } @@ -1947,7 +1952,7 @@ void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels) int attrSource = GetAttribute( "source"); const char* source = mReader->getAttributeValue( attrSource); if( source[0] != '#') - ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\".") % source)); + ThrowException( boost::str( boost::format( "Unknown reference format in url \"%s\" in source attribute of <input> element.") % source)); channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only // read index offset, if per-index <input> @@ -1961,7 +1966,7 @@ void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels) if(attrSet > -1){ attrSet = mReader->getAttributeValueAsInt( attrSet); if(attrSet < 0) - ThrowException( boost::str( boost::format( "Invalid index \"%i\" for set attribute") % (attrSet))); + ThrowException( boost::str( boost::format( "Invalid index \"%i\" in set attribute of <input> element") % (attrSet))); channel.mIndex = attrSet; } @@ -2063,7 +2068,7 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPer { // warn if the vertex channel does not refer to the <vertices> element in the same mesh if( input.mAccessor != pMesh->mVertexID) - ThrowException( "Unsupported vertex referencing scheme. I fucking hate Collada."); + ThrowException( "Unsupported vertex referencing scheme."); continue; } @@ -2155,7 +2160,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si // get a pointer to the start of the data object referred to by the accessor and the local index const float* dataObject = &(acc.mData->mValues[0]) + acc.mOffset + pLocalIndex* acc.mStride; - + // assemble according to the accessors component sub-offset list. We don't care, yet, // what kind of object exactly we're extracting here float obj[4]; @@ -2172,74 +2177,79 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si DefaultLogger::get()->error("Collada: just one vertex position stream supported"); break; case IT_Normal: - // pad to current vertex count if necessary - if( pMesh->mNormals.size() < pMesh->mPositions.size()-1) - pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0)); + // pad to current vertex count if necessary + if( pMesh->mNormals.size() < pMesh->mPositions.size()-1) + pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0)); - // ignore all normal streams except 0 - there can be only one normal - if( pInput.mIndex == 0) + // ignore all normal streams except 0 - there can be only one normal + if( pInput.mIndex == 0) pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex normal stream supported"); break; case IT_Tangent: - // pad to current vertex count if necessary - if( pMesh->mTangents.size() < pMesh->mPositions.size()-1) - pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0)); + // pad to current vertex count if necessary + if( pMesh->mTangents.size() < pMesh->mPositions.size()-1) + pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0)); - // ignore all tangent streams except 0 - there can be only one tangent - if( pInput.mIndex == 0) + // ignore all tangent streams except 0 - there can be only one tangent + if( pInput.mIndex == 0) pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex tangent stream supported"); break; case IT_Bitangent: - // pad to current vertex count if necessary - if( pMesh->mBitangents.size() < pMesh->mPositions.size()-1) - pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1)); + // pad to current vertex count if necessary + if( pMesh->mBitangents.size() < pMesh->mPositions.size()-1) + pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1)); - // ignore all bitangent streams except 0 - there can be only one bitangent - if( pInput.mIndex == 0) + // ignore all bitangent streams except 0 - there can be only one bitangent + if( pInput.mIndex == 0) pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported"); break; case IT_Texcoord: - // up to 4 texture coord sets are fine, ignore the others + // up to 4 texture coord sets are fine, ignore the others if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) - { - // pad to current vertex count if necessary - if( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1) - pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(), - pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0)); + { + // pad to current vertex count if necessary + if( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1) + pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(), + pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0)); pMesh->mTexCoords[pInput.mIndex].push_back( aiVector3D( obj[0], obj[1], obj[2])); if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */ pMesh->mNumUVComponents[pInput.mIndex]=3; } else - { + { DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping."); - } + } break; case IT_Color: - // up to 4 color sets are fine, ignore the others + // up to 4 color sets are fine, ignore the others if( pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) - { - // pad to current vertex count if necessary - if( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1) - pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), - pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1)); + { + // pad to current vertex count if necessary + if( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1) + pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), + pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1)); - pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3])); - } else - { + aiColor4D result(0, 0, 0, 1); + for (size_t i = 0; i < pInput.mResolved->mSize; ++i) + { + result[i] = obj[pInput.mResolved->mSubOffset[i]]; + } + pMesh->mColors[pInput.mIndex].push_back(result); + } else + { DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping."); - } + } break; - default: - // IT_Invalid and IT_Vertex - ai_assert(false && "shouldn't ever get here"); + default: + // IT_Invalid and IT_Vertex + ai_assert(false && "shouldn't ever get here"); } } @@ -2574,18 +2584,18 @@ void ColladaParser::ReadScene() { // should be the first and only occurence if( mRootNode) - ThrowException( "Invalid scene containing multiple root nodes"); + ThrowException( "Invalid scene containing multiple root nodes in <instance_visual_scene> element"); // read the url of the scene to instance. Should be of format "#some_name" int urlIndex = GetAttribute( "url"); const char* url = mReader->getAttributeValue( urlIndex); if( url[0] != '#') - ThrowException( "Unknown reference format"); + ThrowException( "Unknown reference format in <instance_visual_scene> element"); // find the referred scene, skip the leading # NodeLibrary::const_iterator sit = mNodeLibrary.find( url+1); if( sit == mNodeLibrary.end()) - ThrowException( "Unable to resolve visual_scene reference \"" + std::string(url) + "\"."); + ThrowException( "Unable to resolve visual_scene reference \"" + std::string(url) + "\" in <instance_visual_scene> element."); mRootNode = sit->second; } else { SkipElement(); @@ -2637,14 +2647,14 @@ void ColladaParser::TestOpening( const char* pName) { // read element start if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of \"%s\" element.") % pName)); + ThrowException( boost::str( boost::format( "Unexpected end of file while beginning of <%s> element.") % pName)); // whitespace in front is ok, just read again if found if( mReader->getNodeType() == irr::io::EXN_TEXT) if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of \"%s\" element.") % pName)); + ThrowException( boost::str( boost::format( "Unexpected end of file while reading beginning of <%s> element.") % pName)); if( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0) - ThrowException( boost::str( boost::format( "Expected start of \"%s\" element.") % pName)); + ThrowException( boost::str( boost::format( "Expected start of <%s> element.") % pName)); } // ------------------------------------------------------------------------------------------------ @@ -2657,15 +2667,15 @@ void ColladaParser::TestClosing( const char* pName) // if not, read some more if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName)); + ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName)); // whitespace in front is ok, just read again if found if( mReader->getNodeType() == irr::io::EXN_TEXT) if( !mReader->read()) - ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName)); + ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of <%s> element.") % pName)); // but this has the be the closing tag, or we're lost if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0) - ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % pName)); + ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % pName)); } // ------------------------------------------------------------------------------------------------ @@ -2677,7 +2687,7 @@ int ColladaParser::GetAttribute( const char* pAttr) const return index; // attribute not found -> throw an exception - ThrowException( boost::str( boost::format( "Expected attribute \"%s\" at element \"%s\".") % pAttr % mReader->getNodeName())); + ThrowException( boost::str( boost::format( "Expected attribute \"%s\" for element <%s>.") % pAttr % mReader->getNodeName())); return -1; } diff --git a/src/3rdparty/assimp/code/ComputeUVMappingProcess.cpp b/src/3rdparty/assimp/code/ComputeUVMappingProcess.cpp index 2ed14f194..091f6a0bb 100644 --- a/src/3rdparty/assimp/code/ComputeUVMappingProcess.cpp +++ b/src/3rdparty/assimp/code/ComputeUVMappingProcess.cpp @@ -380,7 +380,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& } // ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::ComputeBoxMapping(aiMesh* /*mesh*/, aiVector3D* /*out*/) +void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* ) { DefaultLogger::get()->error("Mapping type currently not implemented"); } diff --git a/src/3rdparty/assimp/code/DefaultIOStream.cpp b/src/3rdparty/assimp/code/DefaultIOStream.cpp index a7d331957..3ce305971 100644 --- a/src/3rdparty/assimp/code/DefaultIOStream.cpp +++ b/src/3rdparty/assimp/code/DefaultIOStream.cpp @@ -110,7 +110,14 @@ size_t DefaultIOStream::FileSize() const if (SIZE_MAX == cachedSize) { - // TODO: Is that really faster if we're already owning a handle to the file? + // Although fseek/ftell would allow us to reuse the exising file handle here, + // it is generally unsafe because: + // - For binary streams, it is not technically well-defined + // - For text files the results are meaningless + // That's why we use the safer variant fstat here. + // + // See here for details: + // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file #if defined _WIN32 && !defined __GNUC__ struct __stat64 fileStat; int err = _stat64( mFilename.c_str(), &fileStat ); diff --git a/src/3rdparty/assimp/code/DefaultLogger.cpp b/src/3rdparty/assimp/code/DefaultLogger.cpp index bfbc5ee28..4f5e59461 100644 --- a/src/3rdparty/assimp/code/DefaultLogger.cpp +++ b/src/3rdparty/assimp/code/DefaultLogger.cpp @@ -253,7 +253,7 @@ void DefaultLogger::OnDebug( const char* message ) if ( m_Severity == Logger::NORMAL ) return; - char msg[MAX_LOG_MESSAGE_LENGTH*2]; + char msg[MAX_LOG_MESSAGE_LENGTH + 16]; ::sprintf(msg,"Debug, T%i: %s", GetThreadID(), message ); WriteToStreams( msg, Logger::Debugging ); @@ -263,7 +263,7 @@ void DefaultLogger::OnDebug( const char* message ) // Logs an info void DefaultLogger::OnInfo( const char* message ) { - char msg[MAX_LOG_MESSAGE_LENGTH*2]; + char msg[MAX_LOG_MESSAGE_LENGTH + 16]; ::sprintf(msg,"Info, T%i: %s", GetThreadID(), message ); WriteToStreams( msg , Logger::Info ); @@ -273,7 +273,7 @@ void DefaultLogger::OnInfo( const char* message ) // Logs a warning void DefaultLogger::OnWarn( const char* message ) { - char msg[MAX_LOG_MESSAGE_LENGTH*2]; + char msg[MAX_LOG_MESSAGE_LENGTH + 16]; ::sprintf(msg,"Warn, T%i: %s", GetThreadID(), message ); WriteToStreams( msg, Logger::Warn ); @@ -283,7 +283,7 @@ void DefaultLogger::OnWarn( const char* message ) // Logs an error void DefaultLogger::OnError( const char* message ) { - char msg[MAX_LOG_MESSAGE_LENGTH*2]; + char msg[MAX_LOG_MESSAGE_LENGTH + 16]; ::sprintf(msg,"Error, T%i: %s", GetThreadID(), message ); WriteToStreams( msg, Logger::Err ); diff --git a/src/3rdparty/assimp/code/Exporter.cpp b/src/3rdparty/assimp/code/Exporter.cpp index d9c204386..9dba5c47c 100644 --- a/src/3rdparty/assimp/code/Exporter.cpp +++ b/src/3rdparty/assimp/code/Exporter.cpp @@ -60,6 +60,7 @@ Here we implement only the C++ interface (Assimp::Exporter). #include "BaseProcess.h" #include "Importer.h" // need this for GetPostProcessingStepInstanceList() +#include "JoinVerticesProcess.h" #include "MakeVerboseFormat.h" #include "ConvertToLHProcess.h" @@ -73,6 +74,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); void ExportSceneCollada(const char*,IOSystem*, const aiScene*); void ExportSceneObj(const char*,IOSystem*, const aiScene*); void ExportSceneSTL(const char*,IOSystem*, const aiScene*); +void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*); void ExportScenePly(const char*,IOSystem*, const aiScene*); void ExportScene3DS(const char*, IOSystem*, const aiScene*) {} @@ -85,13 +87,17 @@ Exporter::ExportFormatEntry gExporters[] = #endif #ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER - Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj), + Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj, + aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */), #endif #ifndef ASSIMP_BUILD_NO_STL_EXPORTER Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL, aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices ), + Exporter::ExportFormatEntry( "stlb", "Stereolithography (binary)", "stl" , &ExportSceneSTLBinary, + aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices + ), #endif #ifndef ASSIMP_BUILD_NO_PLY_EXPORTER @@ -170,6 +176,8 @@ Exporter :: Exporter() Exporter :: ~Exporter() { FreeBlob(); + + delete pimpl; } @@ -196,7 +204,7 @@ bool Exporter :: IsDefaultIOHandler() const // ------------------------------------------------------------------------------------------------ -const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int /*pPreprocessing*/ ) +const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int ) { if (pimpl->blob) { delete pimpl->blob; @@ -222,10 +230,46 @@ const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const // ------------------------------------------------------------------------------------------------ +bool IsVerboseFormat(const aiMesh* mesh) +{ + // avoid slow vector<bool> specialization + std::vector<unsigned int> seen(mesh->mNumVertices,0); + for(unsigned int i = 0; i < mesh->mNumFaces; ++i) { + const aiFace& f = mesh->mFaces[i]; + for(unsigned int j = 0; j < f.mNumIndices; ++j) { + if(++seen[f.mIndices[j]] == 2) { + // found a duplicate index + return false; + } + } + } + return true; +} + + +// ------------------------------------------------------------------------------------------------ +bool IsVerboseFormat(const aiScene* pScene) +{ + for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { + if(!IsVerboseFormat(pScene->mMeshes[i])) { + return false; + } + } + return true; +} + + +// ------------------------------------------------------------------------------------------------ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing ) { ASSIMP_BEGIN_EXCEPTION_REGION(); + // when they create scenes from scratch, users will likely create them not in verbose + // format. They will likely not be aware that there is a flag in the scene to indicate + // this, however. To avoid surprises and bug reports, we check for duplicates in + // meshes upfront. + const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene); + pimpl->mError = ""; for (size_t i = 0; i < pimpl->mExporters.size(); ++i) { const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i]; @@ -247,19 +291,21 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded; // Erase all pp steps that were already applied to this scene - unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv + const unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv && !priv->mIsCopy ? (priv->mPPStepsApplied & ~nonIdempotentSteps) : 0u); // If no extra postprocessing was specified, and we obtained this scene from an // Assimp importer, apply the reverse steps automatically. - if (!pPreprocessing && priv) { - pp |= (nonIdempotentSteps & priv->mPPStepsApplied); - } + // TODO: either drop this, or document it. Otherwise it is just a bad surprise. + //if (!pPreprocessing && priv) { + // pp |= (nonIdempotentSteps & priv->mPPStepsApplied); + //} // If the input scene is not in verbose format, but there is at least postprocessing step that relies on it, // we need to run the MakeVerboseFormat step first. - if (scenecopy->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) { + bool must_join_again = false; + if (!is_verbose_format) { bool verbosify = false; for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { @@ -276,6 +322,10 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const MakeVerboseFormatProcess proc; proc.Execute(scenecopy.get()); + + if(!(exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) { + must_join_again = true; + } } } @@ -320,6 +370,11 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const privOut->mPPStepsApplied |= pp; } + if(must_join_again) { + JoinVerticesProcess proc; + proc.Execute(scenecopy.get()); + } + exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get()); } catch (DeadlyExportError& err) { diff --git a/src/3rdparty/assimp/code/FBXAnimation.cpp b/src/3rdparty/assimp/code/FBXAnimation.cpp new file mode 100644 index 000000000..ccf1d82f4 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXAnimation.cpp @@ -0,0 +1,313 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXAnimation.cpp + * @brief Assimp::FBX::AnimationCurve, Assimp::FBX::AnimationCurveNode, + * Assimp::FBX::AnimationLayer, Assimp::FBX::AnimationStack + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXImporter.h" +#include "FBXImportSettings.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + +// ------------------------------------------------------------------------------------------------ +AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc) +: Object(id, element, name) +{ + const Scope& sc = GetRequiredScope(element); + const Element& KeyTime = GetRequiredElement(sc,"KeyTime"); + const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat"); + + ParseVectorDataArray(keys, KeyTime); + ParseVectorDataArray(values, KeyValueFloat); + + if(keys.size() != values.size()) { + DOMError("the number of key times does not match the number of keyframe values",&KeyTime); + } + + // check if the key times are well-ordered + if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) { + DOMError("the keyframes are not in ascending order",&KeyTime); + } + + const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"]; + if(KeyAttrDataFloat) { + ParseVectorDataArray(attributes, *KeyAttrDataFloat); + } + + const Element* KeyAttrFlags = sc["KeyAttrFlags"]; + if(KeyAttrFlags) { + ParseVectorDataArray(flags, *KeyAttrFlags); + } +} + + +// ------------------------------------------------------------------------------------------------ +AnimationCurve::~AnimationCurve() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc, + const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/) +: Object(id, element, name) +, target() +, doc(doc) +{ + const Scope& sc = GetRequiredScope(element); + + // find target node + const char* whitelist[] = {"Model","NodeAttribute"}; + const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2); + + BOOST_FOREACH(const Connection* con, conns) { + + // link should go for a property + if (!con->PropertyName().length()) { + continue; + } + + if(target_prop_whitelist) { + const char* const s = con->PropertyName().c_str(); + bool ok = false; + for (size_t i = 0; i < whitelist_size; ++i) { + if (!strcmp(s, target_prop_whitelist[i])) { + ok = true; + break; + } + } + + if (!ok) { + throw std::range_error("AnimationCurveNode target property is not in whitelist"); + } + } + + const Object* const ob = con->DestinationObject(); + if(!ob) { + DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element); + continue; + } + + // XXX support constraints as DOM class + //ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob)); + target = ob; + if(!target) { + continue; + } + + prop = con->PropertyName(); + break; + } + + if(!target) { + DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element); + } + + props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false); +} + + +// ------------------------------------------------------------------------------------------------ +AnimationCurveNode::~AnimationCurveNode() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +const AnimationCurveMap& AnimationCurveNode::Curves() const +{ + if(curves.empty()) { + // resolve attached animation curves + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve"); + + BOOST_FOREACH(const Connection* con, conns) { + + // link should go for a property + if (!con->PropertyName().length()) { + continue; + } + + const Object* const ob = con->SourceObject(); + if(!ob) { + DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element); + continue; + } + + const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob); + if(!anim) { + DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element); + continue; + } + + curves[con->PropertyName()] = anim; + } + } + + return curves; +} + + +// ------------------------------------------------------------------------------------------------ +AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc) +: Object(id, element, name) +, doc(doc) +{ + const Scope& sc = GetRequiredScope(element); + + // note: the props table here bears little importance and is usually absent + props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true); +} + + +// ------------------------------------------------------------------------------------------------ +AnimationLayer::~AnimationLayer() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/, + size_t whitelist_size /*= 0*/) const +{ + AnimationCurveNodeList nodes; + + // resolve attached animation nodes + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode"); + nodes.reserve(conns.size()); + + BOOST_FOREACH(const Connection* con, conns) { + + // link should not go to a property + if (con->PropertyName().length()) { + continue; + } + + const Object* const ob = con->SourceObject(); + if(!ob) { + DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element); + continue; + } + + const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob); + if(!anim) { + DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element); + continue; + } + + if(target_prop_whitelist) { + const char* s = anim->TargetProperty().c_str(); + bool ok = false; + for (size_t i = 0; i < whitelist_size; ++i) { + if (!strcmp(s, target_prop_whitelist[i])) { + ok = true; + break; + } + } + if(!ok) { + continue; + } + } + nodes.push_back(anim); + } + + return nodes; // pray for NRVO +} + +// ------------------------------------------------------------------------------------------------ +AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc) +: Object(id, element, name) +{ + const Scope& sc = GetRequiredScope(element); + + // note: we don't currently use any of these properties so we shouldn't bother if it is missing + props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true); + + // resolve attached animation layers + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer"); + layers.reserve(conns.size()); + + BOOST_FOREACH(const Connection* con, conns) { + + // link should not go to a property + if (con->PropertyName().length()) { + continue; + } + + const Object* const ob = con->SourceObject(); + if(!ob) { + DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element); + continue; + } + + const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob); + if(!anim) { + DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element); + continue; + } + layers.push_back(anim); + } +} + + +// ------------------------------------------------------------------------------------------------ +AnimationStack::~AnimationStack() +{ + +} + +} //!FBX +} //!Assimp + +#endif diff --git a/src/3rdparty/assimp/code/FBXBinaryTokenizer.cpp b/src/3rdparty/assimp/code/FBXBinaryTokenizer.cpp new file mode 100644 index 000000000..b5f151c15 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXBinaryTokenizer.cpp @@ -0,0 +1,398 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ +/** @file FBXBinaryTokenizer.cpp + * @brief Implementation of a fake lexer for binary fbx files - + * we emit tokens so the parser needs almost no special handling + * for binary files. + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXTokenizer.h" +#include "FBXUtil.h" + +namespace Assimp { +namespace FBX { + + +// ------------------------------------------------------------------------------------------------ +Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset) + : sbegin(sbegin) + , send(send) + , type(type) + , line(offset) + , column(BINARY_MARKER) +#ifdef DEBUG + , contents(sbegin, static_cast<size_t>(send-sbegin)) +#endif +{ + ai_assert(sbegin); + ai_assert(send); + + // binary tokens may have zero length because they are sometimes dummies + // inserted by TokenizeBinary() + ai_assert(send >= sbegin); +} + + +namespace { + +// ------------------------------------------------------------------------------------------------ +// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError. +void TokenizeError(const std::string& message, unsigned int offset) +{ + throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset)); +} + + +// ------------------------------------------------------------------------------------------------ +uint32_t Offset(const char* begin, const char* cursor) +{ + ai_assert(begin <= cursor); + return static_cast<unsigned int>(cursor - begin); +} + + +// ------------------------------------------------------------------------------------------------ +void TokenizeError(const std::string& message, const char* begin, const char* cursor) +{ + TokenizeError(message, Offset(begin, cursor)); +} + + +// ------------------------------------------------------------------------------------------------ +uint32_t ReadWord(const char* input, const char*& cursor, const char* end) +{ + if(Offset(cursor, end) < 4) { + TokenizeError("cannot ReadWord, out of bounds",input, cursor); + } + + uint32_t word = *reinterpret_cast<const uint32_t*>(cursor); + AI_SWAP4(word); + + cursor += 4; + + return word; +} + + +// ------------------------------------------------------------------------------------------------ +uint8_t ReadByte(const char* input, const char*& cursor, const char* end) +{ + if(Offset(cursor, end) < 1) { + TokenizeError("cannot ReadByte, out of bounds",input, cursor); + } + + uint8_t word = *reinterpret_cast<const uint8_t*>(cursor); + ++cursor; + + return word; +} + + +// ------------------------------------------------------------------------------------------------ +unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end, + bool long_length = false, + bool allow_null = false) +{ + const uint32_t len_len = long_length ? 4 : 1; + if(Offset(cursor, end) < len_len) { + TokenizeError("cannot ReadString, out of bounds reading length",input, cursor); + } + + const uint32_t length = long_length ? ReadWord(input, cursor, end) : ReadByte(input, cursor, end); + + if (Offset(cursor, end) < length) { + TokenizeError("cannot ReadString, length is out of bounds",input, cursor); + } + + sbegin_out = cursor; + cursor += length; + + send_out = cursor; + + if(!allow_null) { + for (unsigned int i = 0; i < length; ++i) { + if(sbegin_out[i] == '\0') { + TokenizeError("failed ReadString, unexpected NUL character in string",input, cursor); + } + } + } + + return length; +} + + + +// ------------------------------------------------------------------------------------------------ +void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end) +{ + if(Offset(cursor, end) < 1) { + TokenizeError("cannot ReadData, out of bounds reading length",input, cursor); + } + + const char type = *cursor; + sbegin_out = cursor++; + + switch(type) + { + // 16 bit int + case 'Y': + cursor += 2; + break; + + // 1 bit bool flag (yes/no) + case 'C': + cursor += 1; + break; + + // 32 bit int + case 'I': + // <- fall thru + + // float + case 'F': + cursor += 4; + break; + + // double + case 'D': + cursor += 8; + break; + + // 64 bit int + case 'L': + cursor += 8; + break; + + // note: do not write cursor += ReadWord(...cursor) as this would be UB + + // raw binary data + case 'R': + { + const uint32_t length = ReadWord(input, cursor, end); + cursor += length; + break; + } + + case 'b': + // TODO: what is the 'b' type code? Right now we just skip over it / + // take the full range we could get + cursor = end; + break; + + // array of * + case 'f': + case 'd': + case 'l': + case 'i': { + + const uint32_t length = ReadWord(input, cursor, end); + const uint32_t encoding = ReadWord(input, cursor, end); + + const uint32_t comp_len = ReadWord(input, cursor, end); + + // compute length based on type and check against the stored value + if(encoding == 0) { + uint32_t stride = 0; + switch(type) + { + case 'f': + case 'i': + stride = 4; + break; + + case 'd': + case 'l': + stride = 8; + break; + + default: + ai_assert(false); + }; + ai_assert(stride > 0); + if(length * stride != comp_len) { + TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor); + } + } + // zip/deflate algorithm (encoding==1)? take given length. anything else? die + else if (encoding != 1) { + TokenizeError("cannot ReadData, unknown encoding",input, cursor); + } + cursor += comp_len; + break; + } + + // string + case 'S': { + const char* sb, *se; + // 0 characters can legally happen in such strings + ReadString(sb, se, input, cursor, end, true, true); + break; + } + default: + TokenizeError("cannot ReadData, unexpected type code: " + std::string(&type, 1),input, cursor); + } + + if(cursor > end) { + TokenizeError("cannot ReadData, the remaining size is too small for the data type: " + std::string(&type, 1),input, cursor); + } + + // the type code is contained in the returned range + send_out = cursor; +} + + +// ------------------------------------------------------------------------------------------------ +bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end) +{ + // the first word contains the offset at which this block ends + const uint32_t end_offset = ReadWord(input, cursor, end); + + // we may get 0 if reading reached the end of the file - + // fbx files have a mysterious extra footer which I don't know + // how to extract any information from, but at least it always + // starts with a 0. + if(!end_offset) { + return false; + } + + if(end_offset > Offset(input, end)) { + TokenizeError("block offset is out of range",input, cursor); + } + else if(end_offset < Offset(input, cursor)) { + TokenizeError("block offset is negative out of range",input, cursor); + } + + // the second data word contains the number of properties in the scope + const uint32_t prop_count = ReadWord(input, cursor, end); + + // the third data word contains the length of the property list + const uint32_t prop_length = ReadWord(input, cursor, end); + + // now comes the name of the scope/key + const char* sbeg, *send; + ReadString(sbeg, send, input, cursor, end); + + output_tokens.push_back(new_Token(sbeg, send, TokenType_KEY, Offset(input, cursor) )); + + // now come the individual properties + const char* begin_cursor = cursor; + for (unsigned int i = 0; i < prop_count; ++i) { + ReadData(sbeg, send, input, cursor, begin_cursor + prop_length); + + output_tokens.push_back(new_Token(sbeg, send, TokenType_DATA, Offset(input, cursor) )); + + if(i != prop_count-1) { + output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_COMMA, Offset(input, cursor) )); + } + } + + if (Offset(begin_cursor, cursor) != prop_length) { + TokenizeError("property length not reached, something is wrong",input, cursor); + } + + // at the end of each nested block, there is a NUL record to indicate + // that the sub-scope exists (i.e. to distinguish between P: and P : {}) + // this NUL record is 13 bytes long. +#define BLOCK_SENTINEL_LENGTH 13 + + if (Offset(input, cursor) < end_offset) { + + if (end_offset - Offset(input, cursor) < BLOCK_SENTINEL_LENGTH) { + TokenizeError("insufficient padding bytes at block end",input, cursor); + } + + output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) )); + + // XXX this is vulnerable to stack overflowing .. + while(Offset(input, cursor) < end_offset - BLOCK_SENTINEL_LENGTH) { + ReadScope(output_tokens, input, cursor, input + end_offset - BLOCK_SENTINEL_LENGTH); + } + output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) )); + + for (unsigned int i = 0; i < BLOCK_SENTINEL_LENGTH; ++i) { + if(cursor[i] != '\0') { + TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor); + } + } + cursor += BLOCK_SENTINEL_LENGTH; + } + + if (Offset(input, cursor) != end_offset) { + TokenizeError("scope length not reached, something is wrong",input, cursor); + } + + return true; +} + + +} + +// ------------------------------------------------------------------------------------------------ +void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length) +{ + ai_assert(input); + + if(length < 0x1b) { + TokenizeError("file is too short",0); + } + + if (strncmp(input,"Kaydara FBX Binary",18)) { + TokenizeError("magic bytes not found",0); + } + + + //uint32_t offset = 0x1b; + + const char* cursor = input + 0x1b; + + while (cursor < input + length) { + if(!ReadScope(output_tokens, input, cursor, input + length)) { + break; + } + } +} + +} // !FBX +} // !Assimp + +#endif
\ No newline at end of file diff --git a/src/3rdparty/assimp/code/FBXCompileConfig.h b/src/3rdparty/assimp/code/FBXCompileConfig.h new file mode 100644 index 000000000..ea7efaddf --- /dev/null +++ b/src/3rdparty/assimp/code/FBXCompileConfig.h @@ -0,0 +1,66 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXCompileConfig.h + * @brief FBX importer compile-time switches + */ +#ifndef INCLUDED_AI_FBX_COMPILECONFIG_H +#define INCLUDED_AI_FBX_COMPILECONFIG_H + +// +#if _MSC_VER > 1500 || (defined __GNUC___) +# define ASSIMP_FBX_USE_UNORDERED_MULTIMAP +# else +# define fbx_unordered_map map +# define fbx_unordered_multimap multimap +#endif + +#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP +# include <unordered_map> +# if _MSC_VER > 1600 +# define fbx_unordered_map unordered_map +# define fbx_unordered_multimap unordered_multimap +# else +# define fbx_unordered_map tr1::unordered_map +# define fbx_unordered_multimap tr1::unordered_multimap +# endif +#endif + +#endif diff --git a/src/3rdparty/assimp/code/FBXConverter.cpp b/src/3rdparty/assimp/code/FBXConverter.cpp new file mode 100644 index 000000000..f623c3ae7 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXConverter.cpp @@ -0,0 +1,2933 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXConverter.cpp + * @brief Implementation of the FBX DOM -> aiScene converter + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include <iterator> +#include <sstream> +#include <boost/tuple/tuple.hpp> + +#include "FBXParser.h" +#include "FBXConverter.h" +#include "FBXDocument.h" +#include "FBXUtil.h" +#include "FBXProperties.h" +#include "FBXImporter.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + + +#define MAGIC_NODE_TAG "_$AssimpFbx$" + +#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L + + // XXX vc9's debugger won't step into anonymous namespaces +//namespace { + +/** Dummy class to encapsulate the conversion process */ +class Converter +{ +public: + + /** the different parts that make up the final local transformation of a fbx node */ + enum TransformationComp + { + TransformationComp_Translation = 0, + TransformationComp_RotationOffset, + TransformationComp_RotationPivot, + TransformationComp_PreRotation, + TransformationComp_Rotation, + TransformationComp_PostRotation, + TransformationComp_RotationPivotInverse, + TransformationComp_ScalingOffset, + TransformationComp_ScalingPivot, + TransformationComp_Scaling, + TransformationComp_ScalingPivotInverse, + TransformationComp_GeometricTranslation, + TransformationComp_GeometricRotation, + TransformationComp_GeometricScaling, + + TransformationComp_MAXIMUM + }; + +public: + + Converter(aiScene* out, const Document& doc) + : defaultMaterialIndex() + , out(out) + , doc(doc) + { + // animations need to be converted first since this will + // populate the node_anim_chain_bits map, which is needed + // to determine which nodes need to be generated. + ConvertAnimations(); + ConvertRootNode(); + + if(doc.Settings().readAllMaterials) { + // unfortunately this means we have to evaluate all objects + BOOST_FOREACH(const ObjectMap::value_type& v,doc.Objects()) { + + const Object* ob = v.second->Get(); + if(!ob) { + continue; + } + + const Material* mat = dynamic_cast<const Material*>(ob); + if(mat) { + + if (materials_converted.find(mat) == materials_converted.end()) { + ConvertMaterial(*mat); + } + } + } + } + + TransferDataToScene(); + + // if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE + // to make sure the scene passes assimp's validation. FBX files + // need not contain geometry (i.e. camera animations, raw armatures). + if (out->mNumMeshes == 0) { + out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; + } + } + + + ~Converter() + { + std::for_each(meshes.begin(),meshes.end(),Util::delete_fun<aiMesh>()); + std::for_each(materials.begin(),materials.end(),Util::delete_fun<aiMaterial>()); + std::for_each(animations.begin(),animations.end(),Util::delete_fun<aiAnimation>()); + std::for_each(lights.begin(),lights.end(),Util::delete_fun<aiLight>()); + std::for_each(cameras.begin(),cameras.end(),Util::delete_fun<aiCamera>()); + } + + +private: + + // ------------------------------------------------------------------------------------------------ + // find scene root and trigger recursive scene conversion + void ConvertRootNode() + { + out->mRootNode = new aiNode(); + out->mRootNode->mName.Set("RootNode"); + + // root has ID 0 + ConvertNodes(0L, *out->mRootNode); + } + + + // ------------------------------------------------------------------------------------------------ + // collect and assign child nodes + void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4()) + { + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model"); + + std::vector<aiNode*> nodes; + nodes.reserve(conns.size()); + + std::vector<aiNode*> nodes_chain; + + try { + BOOST_FOREACH(const Connection* con, conns) { + + // ignore object-property links + if(con->PropertyName().length()) { + continue; + } + + const Object* const object = con->SourceObject(); + if(!object) { + FBXImporter::LogWarn("failed to convert source object for Model link"); + continue; + } + + const Model* const model = dynamic_cast<const Model*>(object); + + if(model) { + nodes_chain.clear(); + + aiMatrix4x4 new_abs_transform = parent_transform; + + // even though there is only a single input node, the design of + // assimp (or rather: the complicated transformation chain that + // is employed by fbx) means that we may need multiple aiNode's + // to represent a fbx node's transformation. + GenerateTransformationNodeChain(*model,nodes_chain); + + ai_assert(nodes_chain.size()); + + const std::string& original_name = FixNodeName(model->Name()); + + // check if any of the nodes in the chain has the name the fbx node + // is supposed to have. If there is none, add another node to + // preserve the name - people might have scripts etc. that rely + // on specific node names. + aiNode* name_carrier = NULL; + BOOST_FOREACH(aiNode* prenode, nodes_chain) { + if ( !strcmp(prenode->mName.C_Str(), original_name.c_str()) ) { + name_carrier = prenode; + break; + } + } + + if(!name_carrier) { + nodes_chain.push_back(new aiNode(original_name)); + name_carrier = nodes_chain.back(); + } + + //setup metadata on newest node + SetupNodeMetadata(*model, *nodes_chain.back()); + + // link all nodes in a row + aiNode* last_parent = &parent; + BOOST_FOREACH(aiNode* prenode, nodes_chain) { + ai_assert(prenode); + + if(last_parent != &parent) { + last_parent->mNumChildren = 1; + last_parent->mChildren = new aiNode*[1]; + last_parent->mChildren[0] = prenode; + } + + prenode->mParent = last_parent; + last_parent = prenode; + + new_abs_transform *= prenode->mTransformation; + } + + // attach geometry + ConvertModel(*model, *nodes_chain.back(), new_abs_transform); + + // attach sub-nodes + ConvertNodes(model->ID(), *nodes_chain.back(), new_abs_transform); + + if(doc.Settings().readLights) { + ConvertLights(*model); + } + + if(doc.Settings().readCameras) { + ConvertCameras(*model); + } + + nodes.push_back(nodes_chain.front()); + nodes_chain.clear(); + } + } + + if(nodes.size()) { + parent.mChildren = new aiNode*[nodes.size()](); + parent.mNumChildren = static_cast<unsigned int>(nodes.size()); + + std::swap_ranges(nodes.begin(),nodes.end(),parent.mChildren); + } + } + catch(std::exception&) { + Util::delete_fun<aiNode> deleter; + std::for_each(nodes.begin(),nodes.end(),deleter); + std::for_each(nodes_chain.begin(),nodes_chain.end(),deleter); + } + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertLights(const Model& model) + { + const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); + BOOST_FOREACH(const NodeAttribute* attr, node_attrs) { + const Light* const light = dynamic_cast<const Light*>(attr); + if(light) { + ConvertLight(model, *light); + } + } + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertCameras(const Model& model) + { + const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); + BOOST_FOREACH(const NodeAttribute* attr, node_attrs) { + const Camera* const cam = dynamic_cast<const Camera*>(attr); + if(cam) { + ConvertCamera(model, *cam); + } + } + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertLight(const Model& model, const Light& light) + { + lights.push_back(new aiLight()); + aiLight* const out_light = lights.back(); + + out_light->mName.Set(FixNodeName(model.Name())); + + const float intensity = light.Intensity(); + const aiVector3D& col = light.Color(); + + out_light->mColorDiffuse = aiColor3D(col.x,col.y,col.z); + out_light->mColorDiffuse.r *= intensity; + out_light->mColorDiffuse.g *= intensity; + out_light->mColorDiffuse.b *= intensity; + + out_light->mColorSpecular = out_light->mColorDiffuse; + + switch(light.LightType()) + { + case Light::Type_Point: + out_light->mType = aiLightSource_POINT; + break; + + case Light::Type_Directional: + out_light->mType = aiLightSource_DIRECTIONAL; + break; + + case Light::Type_Spot: + out_light->mType = aiLightSource_SPOT; + out_light->mAngleOuterCone = AI_DEG_TO_RAD(light.OuterAngle()); + out_light->mAngleInnerCone = AI_DEG_TO_RAD(light.InnerAngle()); + break; + + case Light::Type_Area: + FBXImporter::LogWarn("cannot represent area light, set to UNDEFINED"); + out_light->mType = aiLightSource_UNDEFINED; + break; + + case Light::Type_Volume: + FBXImporter::LogWarn("cannot represent volume light, set to UNDEFINED"); + out_light->mType = aiLightSource_UNDEFINED; + break; + default: + ai_assert(false); + } + + // XXX: how to best convert the near and far decay ranges? + switch(light.DecayType()) + { + case Light::Decay_None: + out_light->mAttenuationConstant = 1.0f; + break; + case Light::Decay_Linear: + out_light->mAttenuationLinear = 1.0f; + break; + case Light::Decay_Quadratic: + out_light->mAttenuationQuadratic = 1.0f; + break; + case Light::Decay_Cubic: + FBXImporter::LogWarn("cannot represent cubic attenuation, set to Quadratic"); + out_light->mAttenuationQuadratic = 1.0f; + break; + default: + ai_assert(false); + } + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertCamera(const Model& model, const Camera& cam) + { + cameras.push_back(new aiCamera()); + aiCamera* const out_camera = cameras.back(); + + out_camera->mName.Set(FixNodeName(model.Name())); + + out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight(); + out_camera->mPosition = cam.Position(); + out_camera->mLookAt = cam.InterestPosition() - out_camera->mPosition; + + // BUG HERE cam.FieldOfView() returns 1.0f every time. 1.0f is default value. + out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView()); + } + + + // ------------------------------------------------------------------------------------------------ + // this returns unified names usable within assimp identifiers (i.e. no space characters - + // while these would be allowed, they are a potential trouble spot so better not use them). + const char* NameTransformationComp(TransformationComp comp) + { + switch(comp) + { + case TransformationComp_Translation: + return "Translation"; + case TransformationComp_RotationOffset: + return "RotationOffset"; + case TransformationComp_RotationPivot: + return "RotationPivot"; + case TransformationComp_PreRotation: + return "PreRotation"; + case TransformationComp_Rotation: + return "Rotation"; + case TransformationComp_PostRotation: + return "PostRotation"; + case TransformationComp_RotationPivotInverse: + return "RotationPivotInverse"; + case TransformationComp_ScalingOffset: + return "ScalingOffset"; + case TransformationComp_ScalingPivot: + return "ScalingPivot"; + case TransformationComp_Scaling: + return "Scaling"; + case TransformationComp_ScalingPivotInverse: + return "ScalingPivotInverse"; + case TransformationComp_GeometricScaling: + return "GeometricScaling"; + case TransformationComp_GeometricRotation: + return "GeometricRotation"; + case TransformationComp_GeometricTranslation: + return "GeometricTranslation"; + case TransformationComp_MAXIMUM: // this is to silence compiler warnings + break; + } + + ai_assert(false); + return NULL; + } + + + // ------------------------------------------------------------------------------------------------ + // note: this returns the REAL fbx property names + const char* NameTransformationCompProperty(TransformationComp comp) + { + switch(comp) + { + case TransformationComp_Translation: + return "Lcl Translation"; + case TransformationComp_RotationOffset: + return "RotationOffset"; + case TransformationComp_RotationPivot: + return "RotationPivot"; + case TransformationComp_PreRotation: + return "PreRotation"; + case TransformationComp_Rotation: + return "Lcl Rotation"; + case TransformationComp_PostRotation: + return "PostRotation"; + case TransformationComp_RotationPivotInverse: + return "RotationPivotInverse"; + case TransformationComp_ScalingOffset: + return "ScalingOffset"; + case TransformationComp_ScalingPivot: + return "ScalingPivot"; + case TransformationComp_Scaling: + return "Lcl Scaling"; + case TransformationComp_ScalingPivotInverse: + return "ScalingPivotInverse"; + case TransformationComp_GeometricScaling: + return "GeometricScaling"; + case TransformationComp_GeometricRotation: + return "GeometricRotation"; + case TransformationComp_GeometricTranslation: + return "GeometricTranslation"; + case TransformationComp_MAXIMUM: // this is to silence compiler warnings + break; + } + + ai_assert(false); + return NULL; + } + + + // ------------------------------------------------------------------------------------------------ + aiVector3D TransformationCompDefaultValue(TransformationComp comp) + { + // XXX a neat way to solve the never-ending special cases for scaling + // would be to do everything in log space! + return comp == TransformationComp_Scaling ? aiVector3D(1.f,1.f,1.f) : aiVector3D(); + } + + + // ------------------------------------------------------------------------------------------------ + void GetRotationMatrix(Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out) + { + if(mode == Model::RotOrder_SphericXYZ) { + FBXImporter::LogError("Unsupported RotationMode: SphericXYZ"); + out = aiMatrix4x4(); + return; + } + + const float angle_epsilon = 1e-6f; + + out = aiMatrix4x4(); + + bool is_id[3] = { true, true, true }; + + aiMatrix4x4 temp[3]; + if(fabs(rotation.z) > angle_epsilon) { + aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(rotation.z),temp[2]); + is_id[2] = false; + } + if(fabs(rotation.y) > angle_epsilon) { + aiMatrix4x4::RotationY(AI_DEG_TO_RAD(rotation.y),temp[1]); + is_id[1] = false; + } + if(fabs(rotation.x) > angle_epsilon) { + aiMatrix4x4::RotationX(AI_DEG_TO_RAD(rotation.x),temp[0]); + is_id[0] = false; + } + + int order[3] = {-1, -1, -1}; + + // note: rotation order is inverted since we're left multiplying as is usual in assimp + switch(mode) + { + case Model::RotOrder_EulerXYZ: + order[0] = 2; + order[1] = 1; + order[2] = 0; + break; + + case Model::RotOrder_EulerXZY: + order[0] = 1; + order[1] = 2; + order[2] = 0; + break; + + case Model::RotOrder_EulerYZX: + order[0] = 0; + order[1] = 2; + order[2] = 1; + break; + + case Model::RotOrder_EulerYXZ: + order[0] = 2; + order[1] = 0; + order[2] = 1; + break; + + case Model::RotOrder_EulerZXY: + order[0] = 1; + order[1] = 0; + order[2] = 2; + break; + + case Model::RotOrder_EulerZYX: + order[0] = 0; + order[1] = 1; + order[2] = 2; + break; + + default: + ai_assert(false); + } + + ai_assert((order[0] >= 0) && (order[0] <= 2)); + ai_assert((order[1] >= 0) && (order[1] <= 2)); + ai_assert((order[2] >= 0) && (order[2] <= 2)); + + if(!is_id[order[0]]) { + out = temp[order[0]]; + } + + if(!is_id[order[1]]) { + out = out * temp[order[1]]; + } + + if(!is_id[order[2]]) { + out = out * temp[order[2]]; + } + } + + + // ------------------------------------------------------------------------------------------------ + /** checks if a node has more than just scaling, rotation and translation components */ + bool NeedsComplexTransformationChain(const Model& model) + { + const PropertyTable& props = model.Props(); + bool ok; + + const float zero_epsilon = 1e-6f; + for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) { + const TransformationComp comp = static_cast<TransformationComp>(i); + + if( comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation || + comp == TransformationComp_GeometricScaling || comp == TransformationComp_GeometricRotation || comp == TransformationComp_GeometricTranslation ) { + continue; + } + + const aiVector3D& v = PropertyGet<aiVector3D>(props,NameTransformationCompProperty(comp),ok); + if(ok && v.SquareLength() > zero_epsilon) { + return true; + } + } + + return false; + } + + + // ------------------------------------------------------------------------------------------------ + // note: name must be a FixNodeName() result + std::string NameTransformationChainNode(const std::string& name, TransformationComp comp) + { + return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp); + } + + + // ------------------------------------------------------------------------------------------------ + /** note: memory for output_nodes will be managed by the caller */ + void GenerateTransformationNodeChain(const Model& model, + std::vector<aiNode*>& output_nodes) + { + const PropertyTable& props = model.Props(); + const Model::RotOrder rot = model.RotationOrder(); + + bool ok; + + aiMatrix4x4 chain[TransformationComp_MAXIMUM]; + std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4()); + + // generate transformation matrices for all the different transformation components + const float zero_epsilon = 1e-6f; + bool is_complex = false; + + const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props,"PreRotation",ok); + if(ok && PreRotation.SquareLength() > zero_epsilon) { + is_complex = true; + + GetRotationMatrix(rot, PreRotation, chain[TransformationComp_PreRotation]); + } + + const aiVector3D& PostRotation = PropertyGet<aiVector3D>(props,"PostRotation",ok); + if(ok && PostRotation.SquareLength() > zero_epsilon) { + is_complex = true; + + GetRotationMatrix(rot, PostRotation, chain[TransformationComp_PostRotation]); + } + + const aiVector3D& RotationPivot = PropertyGet<aiVector3D>(props,"RotationPivot",ok); + if(ok && RotationPivot.SquareLength() > zero_epsilon) { + is_complex = true; + + aiMatrix4x4::Translation(RotationPivot,chain[TransformationComp_RotationPivot]); + aiMatrix4x4::Translation(-RotationPivot,chain[TransformationComp_RotationPivotInverse]); + } + + const aiVector3D& RotationOffset = PropertyGet<aiVector3D>(props,"RotationOffset",ok); + if(ok && RotationOffset.SquareLength() > zero_epsilon) { + is_complex = true; + + aiMatrix4x4::Translation(RotationOffset,chain[TransformationComp_RotationOffset]); + } + + const aiVector3D& ScalingOffset = PropertyGet<aiVector3D>(props,"ScalingOffset",ok); + if(ok && ScalingOffset.SquareLength() > zero_epsilon) { + is_complex = true; + + aiMatrix4x4::Translation(ScalingOffset,chain[TransformationComp_ScalingOffset]); + } + + const aiVector3D& ScalingPivot = PropertyGet<aiVector3D>(props,"ScalingPivot",ok); + if(ok && ScalingPivot.SquareLength() > zero_epsilon) { + is_complex = true; + + aiMatrix4x4::Translation(ScalingPivot,chain[TransformationComp_ScalingPivot]); + aiMatrix4x4::Translation(-ScalingPivot,chain[TransformationComp_ScalingPivotInverse]); + } + + const aiVector3D& Translation = PropertyGet<aiVector3D>(props,"Lcl Translation",ok); + if(ok && Translation.SquareLength() > zero_epsilon) { + aiMatrix4x4::Translation(Translation,chain[TransformationComp_Translation]); + } + + const aiVector3D& Scaling = PropertyGet<aiVector3D>(props,"Lcl Scaling",ok); + if(ok && fabs(Scaling.SquareLength()-1.0f) > zero_epsilon) { + aiMatrix4x4::Scaling(Scaling,chain[TransformationComp_Scaling]); + } + + const aiVector3D& Rotation = PropertyGet<aiVector3D>(props,"Lcl Rotation",ok); + if(ok && Rotation.SquareLength() > zero_epsilon) { + GetRotationMatrix(rot, Rotation, chain[TransformationComp_Rotation]); + } + + const aiVector3D& GeometricScaling = PropertyGet<aiVector3D>(props, "GeometricScaling", ok); + if (ok && fabs(GeometricScaling.SquareLength() - 1.0f) > zero_epsilon) { + aiMatrix4x4::Scaling(GeometricScaling, chain[TransformationComp_GeometricScaling]); + } + + const aiVector3D& GeometricRotation = PropertyGet<aiVector3D>(props, "GeometricRotation", ok); + if (ok && GeometricRotation.SquareLength() > zero_epsilon) { + GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotation]); + } + + const aiVector3D& GeometricTranslation = PropertyGet<aiVector3D>(props, "GeometricTranslation", ok); + if (ok && GeometricTranslation.SquareLength() > zero_epsilon){ + aiMatrix4x4::Translation(GeometricTranslation, chain[TransformationComp_GeometricTranslation]); + } + + // is_complex needs to be consistent with NeedsComplexTransformationChain() + // or the interplay between this code and the animation converter would + // not be guaranteed. + ai_assert(NeedsComplexTransformationChain(model) == is_complex); + + const std::string& name = FixNodeName(model.Name()); + + // now, if we have more than just Translation, Scaling and Rotation, + // we need to generate a full node chain to accommodate for assimp's + // lack to express pivots and offsets. + if(is_complex && doc.Settings().preservePivots) { + FBXImporter::LogInfo("generating full transformation chain for node: " + name); + + // query the anim_chain_bits dictionary to find out which chain elements + // have associated node animation channels. These can not be dropped + // even if they have identity transform in bind pose. + NodeAnimBitMap::const_iterator it = node_anim_chain_bits.find(name); + const unsigned int anim_chain_bitmask = (it == node_anim_chain_bits.end() ? 0 : (*it).second); + + unsigned int bit = 0x1; + for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) { + const TransformationComp comp = static_cast<TransformationComp>(i); + + if (chain[i].IsIdentity() && (anim_chain_bitmask & bit) == 0) { + continue; + } + + aiNode* nd = new aiNode(); + output_nodes.push_back(nd); + + nd->mName.Set(NameTransformationChainNode(name, comp)); + nd->mTransformation = chain[i]; + } + + ai_assert(output_nodes.size()); + return; + } + + // else, we can just multiply the matrices together + aiNode* nd = new aiNode(); + output_nodes.push_back(nd); + + nd->mName.Set(name); + + for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) { + nd->mTransformation = nd->mTransformation * chain[i]; + } + } + + // ------------------------------------------------------------------------------------------------ + + void SetupNodeMetadata(const Model& model, aiNode& nd) + { + const PropertyTable& props = model.Props(); + DirectPropertyMap unparsedProperties = props.GetUnparsedProperties(); + + // create metadata on node + std::size_t numStaticMetaData = 2; + aiMetadata* data = new aiMetadata(); + data->mNumProperties = unparsedProperties.size() + numStaticMetaData; + data->mKeys = new aiString[data->mNumProperties](); + data->mValues = new aiMetadataEntry[data->mNumProperties](); + nd.mMetaData = data; + int index = 0; + + // find user defined properties (3ds Max) + data->Set(index++, "UserProperties", aiString(PropertyGet<std::string>(props, "UDP3DSMAX", ""))); + unparsedProperties.erase("UDP3DSMAX"); + // preserve the info that a node was marked as Null node in the original file. + data->Set(index++, "IsNull", model.IsNull() ? true : false); + + // add unparsed properties to the node's metadata + BOOST_FOREACH(const DirectPropertyMap::value_type& prop, unparsedProperties) { + + // Interpret the property as a concrete type + if (const TypedProperty<bool>* interpreted = prop.second->As<TypedProperty<bool> >()) + data->Set(index++, prop.first, interpreted->Value()); + else if (const TypedProperty<int>* interpreted = prop.second->As<TypedProperty<int> >()) + data->Set(index++, prop.first, interpreted->Value()); + else if (const TypedProperty<uint64_t>* interpreted = prop.second->As<TypedProperty<uint64_t> >()) + data->Set(index++, prop.first, interpreted->Value()); + else if (const TypedProperty<float>* interpreted = prop.second->As<TypedProperty<float> >()) + data->Set(index++, prop.first, interpreted->Value()); + else if (const TypedProperty<aiString>* interpreted = prop.second->As<TypedProperty<aiString> >()) + data->Set(index++, prop.first, interpreted->Value()); + else if (const TypedProperty<aiVector3D>* interpreted = prop.second->As<TypedProperty<aiVector3D> >()) + data->Set(index++, prop.first, interpreted->Value()); + else + assert(false); + } + } + + // ------------------------------------------------------------------------------------------------ + void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform) + { + const std::vector<const Geometry*>& geos = model.GetGeometry(); + + std::vector<unsigned int> meshes; + meshes.reserve(geos.size()); + + BOOST_FOREACH(const Geometry* geo, geos) { + + const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo); + if(mesh) { + const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform); + std::copy(indices.begin(),indices.end(),std::back_inserter(meshes) ); + } + else { + FBXImporter::LogWarn("ignoring unrecognized geometry: " + geo->Name()); + } + } + + if(meshes.size()) { + nd.mMeshes = new unsigned int[meshes.size()](); + nd.mNumMeshes = static_cast<unsigned int>(meshes.size()); + + std::swap_ranges(meshes.begin(),meshes.end(),nd.mMeshes); + } + } + + + // ------------------------------------------------------------------------------------------------ + // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed + std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh,const Model& model, + const aiMatrix4x4& node_global_transform) + { + std::vector<unsigned int> temp; + + MeshMap::const_iterator it = meshes_converted.find(&mesh); + if (it != meshes_converted.end()) { + std::copy((*it).second.begin(),(*it).second.end(),std::back_inserter(temp)); + return temp; + } + + const std::vector<aiVector3D>& vertices = mesh.GetVertices(); + const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts(); + if(vertices.empty() || faces.empty()) { + FBXImporter::LogWarn("ignoring empty geometry: " + mesh.Name()); + return temp; + } + + // one material per mesh maps easily to aiMesh. Multiple material + // meshes need to be split. + const MatIndexArray& mindices = mesh.GetMaterialIndices(); + if (doc.Settings().readMaterials && !mindices.empty()) { + const MatIndexArray::value_type base = mindices[0]; + BOOST_FOREACH(MatIndexArray::value_type index, mindices) { + if(index != base) { + return ConvertMeshMultiMaterial(mesh, model, node_global_transform); + } + } + } + + // faster codepath, just copy the data + temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform)); + return temp; + } + + + // ------------------------------------------------------------------------------------------------ + aiMesh* SetupEmptyMesh(const MeshGeometry& mesh) + { + aiMesh* const out_mesh = new aiMesh(); + meshes.push_back(out_mesh); + meshes_converted[&mesh].push_back(static_cast<unsigned int>(meshes.size()-1)); + + // set name + std::string name = mesh.Name(); + if (name.substr(0,10) == "Geometry::") { + name = name.substr(10); + } + + if(name.length()) { + out_mesh->mName.Set(name); + } + + return out_mesh; + } + + + // ------------------------------------------------------------------------------------------------ + unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model, + const aiMatrix4x4& node_global_transform) + { + const MatIndexArray& mindices = mesh.GetMaterialIndices(); + aiMesh* const out_mesh = SetupEmptyMesh(mesh); + + const std::vector<aiVector3D>& vertices = mesh.GetVertices(); + const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts(); + + // copy vertices + out_mesh->mNumVertices = static_cast<unsigned int>(vertices.size()); + out_mesh->mVertices = new aiVector3D[vertices.size()]; + std::copy(vertices.begin(),vertices.end(),out_mesh->mVertices); + + // generate dummy faces + out_mesh->mNumFaces = static_cast<unsigned int>(faces.size()); + aiFace* fac = out_mesh->mFaces = new aiFace[faces.size()](); + + unsigned int cursor = 0; + BOOST_FOREACH(unsigned int pcount, faces) { + aiFace& f = *fac++; + f.mNumIndices = pcount; + f.mIndices = new unsigned int[pcount]; + switch(pcount) + { + case 1: + out_mesh->mPrimitiveTypes |= aiPrimitiveType_POINT; + break; + case 2: + out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; + break; + case 3: + out_mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; + break; + default: + out_mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; + break; + } + for (unsigned int i = 0; i < pcount; ++i) { + f.mIndices[i] = cursor++; + } + } + + // copy normals + const std::vector<aiVector3D>& normals = mesh.GetNormals(); + if(normals.size()) { + ai_assert(normals.size() == vertices.size()); + + out_mesh->mNormals = new aiVector3D[vertices.size()]; + std::copy(normals.begin(),normals.end(),out_mesh->mNormals); + } + + // copy tangents - assimp requires both tangents and bitangents (binormals) + // to be present, or neither of them. Compute binormals from normals + // and tangents if needed. + const std::vector<aiVector3D>& tangents = mesh.GetTangents(); + const std::vector<aiVector3D>* binormals = &mesh.GetBinormals(); + + if(tangents.size()) { + std::vector<aiVector3D> tempBinormals; + if (!binormals->size()) { + if (normals.size()) { + tempBinormals.resize(normals.size()); + for (unsigned int i = 0; i < tangents.size(); ++i) { + tempBinormals[i] = normals[i] ^ tangents[i]; + } + + binormals = &tempBinormals; + } + else { + binormals = NULL; + } + } + + if(binormals) { + ai_assert(tangents.size() == vertices.size() && binormals->size() == vertices.size()); + + out_mesh->mTangents = new aiVector3D[vertices.size()]; + std::copy(tangents.begin(),tangents.end(),out_mesh->mTangents); + + out_mesh->mBitangents = new aiVector3D[vertices.size()]; + std::copy(binormals->begin(),binormals->end(),out_mesh->mBitangents); + } + } + + // copy texture coords + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { + const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(i); + if(uvs.empty()) { + break; + } + + aiVector3D* out_uv = out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()]; + BOOST_FOREACH(const aiVector2D& v, uvs) { + *out_uv++ = aiVector3D(v.x,v.y,0.0f); + } + + out_mesh->mNumUVComponents[i] = 2; + } + + // copy vertex colors + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) { + const std::vector<aiColor4D>& colors = mesh.GetVertexColors(i); + if(colors.empty()) { + break; + } + + out_mesh->mColors[i] = new aiColor4D[vertices.size()]; + std::copy(colors.begin(),colors.end(),out_mesh->mColors[i]); + } + + if(!doc.Settings().readMaterials || mindices.empty()) { + FBXImporter::LogError("no material assigned to mesh, setting default material"); + out_mesh->mMaterialIndex = GetDefaultMaterial(); + } + else { + ConvertMaterialForMesh(out_mesh,model,mesh,mindices[0]); + } + + if(doc.Settings().readWeights && mesh.DeformerSkin() != NULL) { + ConvertWeights(out_mesh, model, mesh, node_global_transform, NO_MATERIAL_SEPARATION); + } + + return static_cast<unsigned int>(meshes.size() - 1); + } + + + // ------------------------------------------------------------------------------------------------ + std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, + const aiMatrix4x4& node_global_transform) + { + const MatIndexArray& mindices = mesh.GetMaterialIndices(); + ai_assert(mindices.size()); + + std::set<MatIndexArray::value_type> had; + std::vector<unsigned int> indices; + + BOOST_FOREACH(MatIndexArray::value_type index, mindices) { + if(had.find(index) == had.end()) { + + indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, node_global_transform)); + had.insert(index); + } + } + + return indices; + } + + + // ------------------------------------------------------------------------------------------------ + unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model, + MatIndexArray::value_type index, + const aiMatrix4x4& node_global_transform) + { + aiMesh* const out_mesh = SetupEmptyMesh(mesh); + + const MatIndexArray& mindices = mesh.GetMaterialIndices(); + const std::vector<aiVector3D>& vertices = mesh.GetVertices(); + const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts(); + + const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != NULL; + + unsigned int count_faces = 0; + unsigned int count_vertices = 0; + + // count faces + std::vector<unsigned int>::const_iterator itf = faces.begin(); + for(MatIndexArray::const_iterator it = mindices.begin(), + end = mindices.end(); it != end; ++it, ++itf) + { + if ((*it) != index) { + continue; + } + ++count_faces; + count_vertices += *itf; + } + + ai_assert(count_faces); + ai_assert(count_vertices); + + // mapping from output indices to DOM indexing, needed to resolve weights + std::vector<unsigned int> reverseMapping; + + if (process_weights) { + reverseMapping.resize(count_vertices); + } + + // allocate output data arrays, but don't fill them yet + out_mesh->mNumVertices = count_vertices; + out_mesh->mVertices = new aiVector3D[count_vertices]; + + out_mesh->mNumFaces = count_faces; + aiFace* fac = out_mesh->mFaces = new aiFace[count_faces](); + + + // allocate normals + const std::vector<aiVector3D>& normals = mesh.GetNormals(); + if(normals.size()) { + ai_assert(normals.size() == vertices.size()); + out_mesh->mNormals = new aiVector3D[vertices.size()]; + } + + // allocate tangents, binormals. + const std::vector<aiVector3D>& tangents = mesh.GetTangents(); + const std::vector<aiVector3D>* binormals = &mesh.GetBinormals(); + + if(tangents.size()) { + std::vector<aiVector3D> tempBinormals; + if (!binormals->size()) { + if (normals.size()) { + // XXX this computes the binormals for the entire mesh, not only + // the part for which we need them. + tempBinormals.resize(normals.size()); + for (unsigned int i = 0; i < tangents.size(); ++i) { + tempBinormals[i] = normals[i] ^ tangents[i]; + } + + binormals = &tempBinormals; + } + else { + binormals = NULL; + } + } + + if(binormals) { + ai_assert(tangents.size() == vertices.size() && binormals->size() == vertices.size()); + + out_mesh->mTangents = new aiVector3D[vertices.size()]; + out_mesh->mBitangents = new aiVector3D[vertices.size()]; + } + } + + // allocate texture coords + unsigned int num_uvs = 0; + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i, ++num_uvs) { + const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(i); + if(uvs.empty()) { + break; + } + + out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()]; + out_mesh->mNumUVComponents[i] = 2; + } + + // allocate vertex colors + unsigned int num_vcs = 0; + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i, ++num_vcs) { + const std::vector<aiColor4D>& colors = mesh.GetVertexColors(i); + if(colors.empty()) { + break; + } + + out_mesh->mColors[i] = new aiColor4D[vertices.size()]; + } + + unsigned int cursor = 0, in_cursor = 0; + + itf = faces.begin(); + for(MatIndexArray::const_iterator it = mindices.begin(), + end = mindices.end(); it != end; ++it, ++itf) + { + const unsigned int pcount = *itf; + if ((*it) != index) { + in_cursor += pcount; + continue; + } + + aiFace& f = *fac++; + + f.mNumIndices = pcount; + f.mIndices = new unsigned int[pcount]; + switch(pcount) + { + case 1: + out_mesh->mPrimitiveTypes |= aiPrimitiveType_POINT; + break; + case 2: + out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE; + break; + case 3: + out_mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; + break; + default: + out_mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; + break; + } + for (unsigned int i = 0; i < pcount; ++i, ++cursor, ++in_cursor) { + f.mIndices[i] = cursor; + + if(reverseMapping.size()) { + reverseMapping[cursor] = in_cursor; + } + + out_mesh->mVertices[cursor] = vertices[in_cursor]; + + if(out_mesh->mNormals) { + out_mesh->mNormals[cursor] = normals[in_cursor]; + } + + if(out_mesh->mTangents) { + out_mesh->mTangents[cursor] = tangents[in_cursor]; + out_mesh->mBitangents[cursor] = (*binormals)[in_cursor]; + } + + for (unsigned int i = 0; i < num_uvs; ++i) { + const std::vector<aiVector2D>& uvs = mesh.GetTextureCoords(i); + out_mesh->mTextureCoords[i][cursor] = aiVector3D(uvs[in_cursor].x,uvs[in_cursor].y, 0.0f); + } + + for (unsigned int i = 0; i < num_vcs; ++i) { + const std::vector<aiColor4D>& cols = mesh.GetVertexColors(i); + out_mesh->mColors[i][cursor] = cols[in_cursor]; + } + } + } + + ConvertMaterialForMesh(out_mesh,model,mesh,index); + + if(process_weights) { + ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping); + } + + return static_cast<unsigned int>(meshes.size() - 1); + } + + static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */ + static_cast<unsigned int>(-1); + + + // ------------------------------------------------------------------------------------------------ + /** - if materialIndex == NO_MATERIAL_SEPARATION, materials are not taken into + * account when determining which weights to include. + * - outputVertStartIndices is only used when a material index is specified, it gives for + * each output vertex the DOM index it maps to. */ + void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo, + const aiMatrix4x4& node_global_transform = aiMatrix4x4(), + unsigned int materialIndex = NO_MATERIAL_SEPARATION, + std::vector<unsigned int>* outputVertStartIndices = NULL) + { + ai_assert(geo.DeformerSkin()); + + std::vector<size_t> out_indices; + std::vector<size_t> index_out_indices; + std::vector<size_t> count_out_indices; + + const Skin& sk = *geo.DeformerSkin(); + + std::vector<aiBone*> bones; + bones.reserve(sk.Clusters().size()); + + const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION; + ai_assert(no_mat_check || outputVertStartIndices); + + try { + + BOOST_FOREACH(const Cluster* cluster, sk.Clusters()) { + ai_assert(cluster); + + const WeightIndexArray& indices = cluster->GetIndices(); + + if(indices.empty()) { + continue; + } + + const MatIndexArray& mats = geo.GetMaterialIndices(); + + bool ok = false; + + const size_t no_index_sentinel = std::numeric_limits<size_t>::max(); + + count_out_indices.clear(); + index_out_indices.clear(); + out_indices.clear(); + + // now check if *any* of these weights is contained in the output mesh, + // taking notes so we don't need to do it twice. + BOOST_FOREACH(WeightIndexArray::value_type index, indices) { + + unsigned int count; + const unsigned int* const out_idx = geo.ToOutputVertexIndex(index, count); + + index_out_indices.push_back(no_index_sentinel); + count_out_indices.push_back(0); + + for(unsigned int i = 0; i < count; ++i) { + if (no_mat_check || static_cast<size_t>(mats[geo.FaceForVertexIndex(out_idx[i])]) == materialIndex) { + + if (index_out_indices.back() == no_index_sentinel) { + index_out_indices.back() = out_indices.size(); + + } + + if (no_mat_check) { + out_indices.push_back(out_idx[i]); + } + else { + // this extra lookup is in O(logn), so the entire algorithm becomes O(nlogn) + const std::vector<unsigned int>::iterator it = std::lower_bound( + outputVertStartIndices->begin(), + outputVertStartIndices->end(), + out_idx[i] + ); + + out_indices.push_back(std::distance(outputVertStartIndices->begin(), it)); + } + + ++count_out_indices.back(); + ok = true; + } + } + } + + // if we found at least one, generate the output bones + // XXX this could be heavily simplified by collecting the bone + // data in a single step. + if (ok) { + ConvertCluster(bones, model, *cluster, out_indices, index_out_indices, + count_out_indices, node_global_transform); + } + } + } + catch (std::exception&) { + std::for_each(bones.begin(),bones.end(),Util::delete_fun<aiBone>()); + throw; + } + + if(bones.empty()) { + return; + } + + out->mBones = new aiBone*[bones.size()](); + out->mNumBones = static_cast<unsigned int>(bones.size()); + + std::swap_ranges(bones.begin(),bones.end(),out->mBones); + } + + + + // ------------------------------------------------------------------------------------------------ + void ConvertCluster(std::vector<aiBone*>& bones, const Model& model, const Cluster& cl, + std::vector<size_t>& out_indices, + std::vector<size_t>& index_out_indices, + std::vector<size_t>& count_out_indices, + const aiMatrix4x4& node_global_transform) + { + + aiBone* const bone = new aiBone(); + bones.push_back(bone); + + bone->mName = FixNodeName(cl.TargetNode()->Name()); + + bone->mOffsetMatrix = cl.TransformLink(); + bone->mOffsetMatrix.Inverse(); + + bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform; + + bone->mNumWeights = static_cast<unsigned int>(out_indices.size()); + aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()]; + + const size_t no_index_sentinel = std::numeric_limits<size_t>::max(); + const WeightArray& weights = cl.GetWeights(); + + const size_t c = index_out_indices.size(); + for (size_t i = 0; i < c; ++i) { + const size_t index_index = index_out_indices[i]; + + if (index_index == no_index_sentinel) { + continue; + } + + const size_t cc = count_out_indices[i]; + for (size_t j = 0; j < cc; ++j) { + aiVertexWeight& out_weight = *cursor++; + + out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]); + out_weight.mWeight = weights[i]; + } + } + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo, + MatIndexArray::value_type materialIndex) + { + // locate source materials for this mesh + const std::vector<const Material*>& mats = model.GetMaterials(); + if (static_cast<unsigned int>(materialIndex) >= mats.size() || materialIndex < 0) { + FBXImporter::LogError("material index out of bounds, setting default material"); + out->mMaterialIndex = GetDefaultMaterial(); + return; + } + + const Material* const mat = mats[materialIndex]; + MaterialMap::const_iterator it = materials_converted.find(mat); + if (it != materials_converted.end()) { + out->mMaterialIndex = (*it).second; + return; + } + + out->mMaterialIndex = ConvertMaterial(*mat); + materials_converted[mat] = out->mMaterialIndex; + } + + + // ------------------------------------------------------------------------------------------------ + unsigned int GetDefaultMaterial() + { + if (defaultMaterialIndex) { + return defaultMaterialIndex - 1; + } + + aiMaterial* out_mat = new aiMaterial(); + materials.push_back(out_mat); + + const aiColor3D diffuse = aiColor3D(0.8f,0.8f,0.8f); + out_mat->AddProperty(&diffuse,1,AI_MATKEY_COLOR_DIFFUSE); + + aiString s; + s.Set(AI_DEFAULT_MATERIAL_NAME); + + out_mat->AddProperty(&s,AI_MATKEY_NAME); + + defaultMaterialIndex = static_cast<unsigned int>(materials.size()); + return defaultMaterialIndex - 1; + } + + + // ------------------------------------------------------------------------------------------------ + // Material -> aiMaterial + unsigned int ConvertMaterial(const Material& material) + { + const PropertyTable& props = material.Props(); + + // generate empty output material + aiMaterial* out_mat = new aiMaterial(); + materials_converted[&material] = static_cast<unsigned int>(materials.size()); + + materials.push_back(out_mat); + + aiString str; + + // stip Material:: prefix + std::string name = material.Name(); + if(name.substr(0,10) == "Material::") { + name = name.substr(10); + } + + // set material name if not empty - this could happen + // and there should be no key for it in this case. + if(name.length()) { + str.Set(name); + out_mat->AddProperty(&str,AI_MATKEY_NAME); + } + + // shading stuff and colors + SetShadingPropertiesCommon(out_mat,props); + + // texture assignments + SetTextureProperties(out_mat,material.Textures()); + SetTextureProperties(out_mat,material.LayeredTextures()); + + return static_cast<unsigned int>(materials.size() - 1); + } + + + // ------------------------------------------------------------------------------------------------ + void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, + const std::string& propName, + aiTextureType target) + { + TextureMap::const_iterator it = textures.find(propName); + if(it == textures.end()) { + return; + } + + const Texture* const tex = (*it).second; + if(tex !=0 ) + { + aiString path; + path.Set(tex->RelativeFilename()); + + out_mat->AddProperty(&path,_AI_MATKEY_TEXTURE_BASE,target,0); + + aiUVTransform uvTrafo; + // XXX handle all kinds of UV transformations + uvTrafo.mScaling = tex->UVScaling(); + uvTrafo.mTranslation = tex->UVTranslation(); + out_mat->AddProperty(&uvTrafo,1,_AI_MATKEY_UVTRANSFORM_BASE,target,0); + + const PropertyTable& props = tex->Props(); + + int uvIndex = 0; + + bool ok; + const std::string& uvSet = PropertyGet<std::string>(props,"UVSet",ok); + if(ok) { + // "default" is the name which usually appears in the FbxFileTexture template + if(uvSet != "default" && uvSet.length()) { + // this is a bit awkward - we need to find a mesh that uses this + // material and scan its UV channels for the given UV name because + // assimp references UV channels by index, not by name. + + // XXX: the case that UV channels may appear in different orders + // in meshes is unhandled. A possible solution would be to sort + // the UV channels alphabetically, but this would have the side + // effect that the primary (first) UV channel would sometimes + // be moved, causing trouble when users read only the first + // UV channel and ignore UV channel assignments altogether. + + const unsigned int matIndex = static_cast<unsigned int>(std::distance(materials.begin(), + std::find(materials.begin(),materials.end(),out_mat) + )); + + uvIndex = -1; + BOOST_FOREACH(const MeshMap::value_type& v,meshes_converted) { + const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*> (v.first); + if(!mesh) { + continue; + } + + const MatIndexArray& mats = mesh->GetMaterialIndices(); + if(std::find(mats.begin(),mats.end(),matIndex) == mats.end()) { + continue; + } + + int index = -1; + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { + if(mesh->GetTextureCoords(i).empty()) { + break; + } + const std::string& name = mesh->GetTextureCoordChannelName(i); + if(name == uvSet) { + index = static_cast<int>(i); + break; + } + } + if(index == -1) { + FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + continue; + } + + if(uvIndex == -1) { + uvIndex = index; + } + else { + FBXImporter::LogWarn("the UV channel named " + uvSet + + " appears at different positions in meshes, results will be wrong"); + } + } + + if(uvIndex == -1) { + FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); + uvIndex = 0; + } + } + } + + out_mat->AddProperty(&uvIndex,1,_AI_MATKEY_UVWSRC_BASE,target,0); + } + } + + // ------------------------------------------------------------------------------------------------ + void TrySetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, + const std::string& propName, + aiTextureType target) + { + LayeredTextureMap::const_iterator it = layeredTextures.find(propName); + if(it == layeredTextures.end()) { + return; + } + + const Texture* const tex = (*it).second->getTexture(); + + aiString path; + path.Set(tex->RelativeFilename()); + + out_mat->AddProperty(&path,_AI_MATKEY_TEXTURE_BASE,target,0); + + aiUVTransform uvTrafo; + // XXX handle all kinds of UV transformations + uvTrafo.mScaling = tex->UVScaling(); + uvTrafo.mTranslation = tex->UVTranslation(); + out_mat->AddProperty(&uvTrafo,1,_AI_MATKEY_UVTRANSFORM_BASE,target,0); + + const PropertyTable& props = tex->Props(); + + int uvIndex = 0; + + bool ok; + const std::string& uvSet = PropertyGet<std::string>(props,"UVSet",ok); + if(ok) { + // "default" is the name which usually appears in the FbxFileTexture template + if(uvSet != "default" && uvSet.length()) { + // this is a bit awkward - we need to find a mesh that uses this + // material and scan its UV channels for the given UV name because + // assimp references UV channels by index, not by name. + + // XXX: the case that UV channels may appear in different orders + // in meshes is unhandled. A possible solution would be to sort + // the UV channels alphabetically, but this would have the side + // effect that the primary (first) UV channel would sometimes + // be moved, causing trouble when users read only the first + // UV channel and ignore UV channel assignments altogether. + + const unsigned int matIndex = static_cast<unsigned int>(std::distance(materials.begin(), + std::find(materials.begin(),materials.end(),out_mat) + )); + + uvIndex = -1; + BOOST_FOREACH(const MeshMap::value_type& v,meshes_converted) { + const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*> (v.first); + if(!mesh) { + continue; + } + + const MatIndexArray& mats = mesh->GetMaterialIndices(); + if(std::find(mats.begin(),mats.end(),matIndex) == mats.end()) { + continue; + } + + int index = -1; + for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { + if(mesh->GetTextureCoords(i).empty()) { + break; + } + const std::string& name = mesh->GetTextureCoordChannelName(i); + if(name == uvSet) { + index = static_cast<int>(i); + break; + } + } + if(index == -1) { + FBXImporter::LogWarn("did not find UV channel named " + uvSet + " in a mesh using this material"); + continue; + } + + if(uvIndex == -1) { + uvIndex = index; + } + else { + FBXImporter::LogWarn("the UV channel named " + uvSet + + " appears at different positions in meshes, results will be wrong"); + } + } + + if(uvIndex == -1) { + FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel"); + uvIndex = 0; + } + } + } + + out_mat->AddProperty(&uvIndex,1,_AI_MATKEY_UVWSRC_BASE,target,0); + } + + // ------------------------------------------------------------------------------------------------ + void SetTextureProperties(aiMaterial* out_mat, const TextureMap& textures) + { + TrySetTextureProperties(out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE); + TrySetTextureProperties(out_mat, textures, "AmbientColor", aiTextureType_AMBIENT); + TrySetTextureProperties(out_mat, textures, "EmissiveColor", aiTextureType_EMISSIVE); + TrySetTextureProperties(out_mat, textures, "SpecularColor", aiTextureType_SPECULAR); + TrySetTextureProperties(out_mat, textures, "TransparentColor", aiTextureType_OPACITY); + TrySetTextureProperties(out_mat, textures, "ReflectionColor", aiTextureType_REFLECTION); + TrySetTextureProperties(out_mat, textures, "DisplacementColor", aiTextureType_DISPLACEMENT); + TrySetTextureProperties(out_mat, textures, "NormalMap", aiTextureType_NORMALS); + TrySetTextureProperties(out_mat, textures, "Bump", aiTextureType_HEIGHT); + TrySetTextureProperties(out_mat, textures, "ShininessExponent", aiTextureType_SHININESS); + } + + // ------------------------------------------------------------------------------------------------ + void SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures) + { + TrySetTextureProperties(out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE); + TrySetTextureProperties(out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT); + TrySetTextureProperties(out_mat, layeredTextures, "EmissiveColor", aiTextureType_EMISSIVE); + TrySetTextureProperties(out_mat, layeredTextures, "SpecularColor", aiTextureType_SPECULAR); + TrySetTextureProperties(out_mat, layeredTextures, "TransparentColor", aiTextureType_OPACITY); + TrySetTextureProperties(out_mat, layeredTextures, "ReflectionColor", aiTextureType_REFLECTION); + TrySetTextureProperties(out_mat, layeredTextures, "DisplacementColor", aiTextureType_DISPLACEMENT); + TrySetTextureProperties(out_mat, layeredTextures, "NormalMap", aiTextureType_NORMALS); + TrySetTextureProperties(out_mat, layeredTextures, "Bump", aiTextureType_HEIGHT); + TrySetTextureProperties(out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS); + } + + + // ------------------------------------------------------------------------------------------------ + aiColor3D GetColorPropertyFromMaterial(const PropertyTable& props, const std::string& baseName, + bool& result) + { + result = true; + + bool ok; + const aiVector3D& Diffuse = PropertyGet<aiVector3D>(props,baseName,ok); + if(ok) { + return aiColor3D(Diffuse.x,Diffuse.y,Diffuse.z); + } + else { + aiVector3D DiffuseColor = PropertyGet<aiVector3D>(props,baseName + "Color",ok); + if(ok) { + float DiffuseFactor = PropertyGet<float>(props,baseName + "Factor",ok); + if(ok) { + DiffuseColor *= DiffuseFactor; + } + + return aiColor3D(DiffuseColor.x,DiffuseColor.y,DiffuseColor.z); + } + } + result = false; + return aiColor3D(0.0f,0.0f,0.0f); + } + + + // ------------------------------------------------------------------------------------------------ + void SetShadingPropertiesCommon(aiMaterial* out_mat, const PropertyTable& props) + { + // set shading properties. There are various, redundant ways in which FBX materials + // specify their shading settings (depending on shading models, prop + // template etc.). No idea which one is right in a particular context. + // Just try to make sense of it - there's no spec to verify this against, + // so why should we. + bool ok; + const aiColor3D& Diffuse = GetColorPropertyFromMaterial(props,"Diffuse",ok); + if(ok) { + out_mat->AddProperty(&Diffuse,1,AI_MATKEY_COLOR_DIFFUSE); + } + + const aiColor3D& Emissive = GetColorPropertyFromMaterial(props,"Emissive",ok); + if(ok) { + out_mat->AddProperty(&Emissive,1,AI_MATKEY_COLOR_EMISSIVE); + } + + const aiColor3D& Ambient = GetColorPropertyFromMaterial(props,"Ambient",ok); + if(ok) { + out_mat->AddProperty(&Ambient,1,AI_MATKEY_COLOR_AMBIENT); + } + + const aiColor3D& Specular = GetColorPropertyFromMaterial(props,"Specular",ok); + if(ok) { + out_mat->AddProperty(&Specular,1,AI_MATKEY_COLOR_SPECULAR); + } + + const float Opacity = PropertyGet<float>(props,"Opacity",ok); + if(ok) { + out_mat->AddProperty(&Opacity,1,AI_MATKEY_OPACITY); + } + + const float Reflectivity = PropertyGet<float>(props,"Reflectivity",ok); + if(ok) { + out_mat->AddProperty(&Reflectivity,1,AI_MATKEY_REFLECTIVITY); + } + + const float Shininess = PropertyGet<float>(props,"Shininess",ok); + if(ok) { + out_mat->AddProperty(&Shininess,1,AI_MATKEY_SHININESS_STRENGTH); + } + + const float ShininessExponent = PropertyGet<float>(props,"ShininessExponent",ok); + if(ok) { + out_mat->AddProperty(&ShininessExponent,1,AI_MATKEY_SHININESS); + } + } + + + // ------------------------------------------------------------------------------------------------ + // get the number of fps for a FrameRate enumerated value + static double FrameRateToDouble(FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0) + { + switch(fp) { + case FileGlobalSettings::FrameRate_DEFAULT: + return 1.0; + + case FileGlobalSettings::FrameRate_120: + return 120.0; + + case FileGlobalSettings::FrameRate_100: + return 100.0; + + case FileGlobalSettings::FrameRate_60: + return 60.0; + + case FileGlobalSettings::FrameRate_50: + return 50.0; + + case FileGlobalSettings::FrameRate_48: + return 48.0; + + case FileGlobalSettings::FrameRate_30: + case FileGlobalSettings::FrameRate_30_DROP: + return 30.0; + + case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME: + case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME: + return 29.9700262; + + case FileGlobalSettings::FrameRate_PAL: + return 25.0; + + case FileGlobalSettings::FrameRate_CINEMA: + return 24.0; + + case FileGlobalSettings::FrameRate_1000: + return 1000.0; + + case FileGlobalSettings::FrameRate_CINEMA_ND: + return 23.976; + + case FileGlobalSettings::FrameRate_CUSTOM: + return customFPSVal; + + case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings + break; + } + + ai_assert(false); + return -1.0f; + } + + + // ------------------------------------------------------------------------------------------------ + // convert animation data to aiAnimation et al + void ConvertAnimations() + { + // first of all determine framerate + const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode(); + const float custom = doc.GlobalSettings().CustomFrameRate(); + anim_fps = FrameRateToDouble(fps, custom); + + const std::vector<const AnimationStack*>& animations = doc.AnimationStacks(); + BOOST_FOREACH(const AnimationStack* stack, animations) { + ConvertAnimationStack(*stack); + } + } + + + // ------------------------------------------------------------------------------------------------ + // rename a node already partially converted. fixed_name is a string previously returned by + // FixNodeName, new_name specifies the string FixNodeName should return on all further invocations + // which would previously have returned the old value. + // + // this also updates names in node animations, cameras and light sources and is thus slow. + // + // NOTE: the caller is responsible for ensuring that the new name is unique and does + // not collide with any other identifiers. The best way to ensure this is to only + // append to the old name, which is guaranteed to match these requirements. + void RenameNode(const std::string& fixed_name, const std::string& new_name) + { + ai_assert(node_names.find(fixed_name) != node_names.end()); + ai_assert(node_names.find(new_name) == node_names.end()); + + renamed_nodes[fixed_name] = new_name; + + const aiString fn(fixed_name); + + BOOST_FOREACH(aiCamera* cam, cameras) { + if (cam->mName == fn) { + cam->mName.Set(new_name); + break; + } + } + + BOOST_FOREACH(aiLight* light, lights) { + if (light->mName == fn) { + light->mName.Set(new_name); + break; + } + } + + BOOST_FOREACH(aiAnimation* anim, animations) { + for (unsigned int i = 0; i < anim->mNumChannels; ++i) { + aiNodeAnim* const na = anim->mChannels[i]; + if (na->mNodeName == fn) { + na->mNodeName.Set(new_name); + break; + } + } + } + } + + + // ------------------------------------------------------------------------------------------------ + // takes a fbx node name and returns the identifier to be used in the assimp output scene. + // the function is guaranteed to provide consistent results over multiple invocations + // UNLESS RenameNode() is called for a particular node name. + std::string FixNodeName(const std::string& name) + { + // strip Model:: prefix, avoiding ambiguities (i.e. don't strip if + // this causes ambiguities, well possible between empty identifiers, + // such as "Model::" and ""). Make sure the behaviour is consistent + // across multiple calls to FixNodeName(). + if(name.substr(0,7) == "Model::") { + std::string temp = name.substr(7); + + const NodeNameMap::const_iterator it = node_names.find(temp); + if (it != node_names.end()) { + if (!(*it).second) { + return FixNodeName(name + "_"); + } + } + node_names[temp] = true; + + const NameNameMap::const_iterator rit = renamed_nodes.find(temp); + return rit == renamed_nodes.end() ? temp : (*rit).second; + } + + const NodeNameMap::const_iterator it = node_names.find(name); + if (it != node_names.end()) { + if ((*it).second) { + return FixNodeName(name + "_"); + } + } + node_names[name] = false; + + const NameNameMap::const_iterator rit = renamed_nodes.find(name); + return rit == renamed_nodes.end() ? name : (*rit).second; + } + + + typedef std::map<const AnimationCurveNode*, const AnimationLayer*> LayerMap; + + // XXX: better use multi_map .. + typedef std::map<std::string, std::vector<const AnimationCurveNode*> > NodeMap; + + + // ------------------------------------------------------------------------------------------------ + void ConvertAnimationStack(const AnimationStack& st) + { + const AnimationLayerList& layers = st.Layers(); + if(layers.empty()) { + return; + } + + aiAnimation* const anim = new aiAnimation(); + animations.push_back(anim); + + // strip AnimationStack:: prefix + std::string name = st.Name(); + if(name.substr(0,16) == "AnimationStack::") { + name = name.substr(16); + } + + anim->mName.Set(name); + + // need to find all nodes for which we need to generate node animations - + // it may happen that we need to merge multiple layers, though. + NodeMap node_map; + + // reverse mapping from curves to layers, much faster than querying + // the FBX DOM for it. + LayerMap layer_map; + + const char* prop_whitelist[] = { + "Lcl Scaling", + "Lcl Rotation", + "Lcl Translation" + }; + + BOOST_FOREACH(const AnimationLayer* layer, layers) { + ai_assert(layer); + + const AnimationCurveNodeList& nodes = layer->Nodes(prop_whitelist, 3); + BOOST_FOREACH(const AnimationCurveNode* node, nodes) { + ai_assert(node); + + const Model* const model = dynamic_cast<const Model*>(node->Target()); + // this can happen - it could also be a NodeAttribute (i.e. for camera animations) + if(!model) { + continue; + } + + const std::string& name = FixNodeName(model->Name()); + node_map[name].push_back(node); + + layer_map[node] = layer; + } + } + + // generate node animations + std::vector<aiNodeAnim*> node_anims; + + double min_time = 1e10; + double max_time = -1e10; + + try { + BOOST_FOREACH(const NodeMap::value_type& kv, node_map) { + GenerateNodeAnimations(node_anims, + kv.first, + kv.second, + layer_map, + max_time, + min_time); + } + } + catch(std::exception&) { + std::for_each(node_anims.begin(), node_anims.end(), Util::delete_fun<aiNodeAnim>()); + throw; + } + + if(node_anims.size()) { + anim->mChannels = new aiNodeAnim*[node_anims.size()](); + anim->mNumChannels = static_cast<unsigned int>(node_anims.size()); + + std::swap_ranges(node_anims.begin(),node_anims.end(),anim->mChannels); + } + else { + // empty animations would fail validation, so drop them + delete anim; + animations.pop_back(); + FBXImporter::LogInfo("ignoring empty AnimationStack (using IK?): " + name); + return; + } + + // for some mysterious reason, mDuration is simply the maximum key -- the + // validator always assumes animations to start at zero. + anim->mDuration = max_time /*- min_time */; + anim->mTicksPerSecond = anim_fps; + } + + + // ------------------------------------------------------------------------------------------------ + void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims, + const std::string& fixed_name, + const std::vector<const AnimationCurveNode*>& curves, + const LayerMap& layer_map, + double& max_time, + double& min_time) + { + + NodeMap node_property_map; + ai_assert(curves.size()); + + // sanity check whether the input is ok +#ifdef ASSIMP_BUILD_DEBUG + { const Object* target = NULL; + BOOST_FOREACH(const AnimationCurveNode* node, curves) { + if(!target) { + target = node->Target(); + } + ai_assert(node->Target() == target); + }} +#endif + + const AnimationCurveNode* curve_node = NULL; + BOOST_FOREACH(const AnimationCurveNode* node, curves) { + ai_assert(node); + + if (node->TargetProperty().empty()) { + FBXImporter::LogWarn("target property for animation curve not set: " + node->Name()); + continue; + } + + curve_node = node; + if (node->Curves().empty()) { + FBXImporter::LogWarn("no animation curves assigned to AnimationCurveNode: " + node->Name()); + continue; + } + + node_property_map[node->TargetProperty()].push_back(node); + } + + ai_assert(curve_node); + ai_assert(curve_node->TargetAsModel()); + + const Model& target = *curve_node->TargetAsModel(); + + // check for all possible transformation components + NodeMap::const_iterator chain[TransformationComp_MAXIMUM]; + + bool has_any = false; + bool has_complex = false; + + for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) { + const TransformationComp comp = static_cast<TransformationComp>(i); + + // inverse pivots don't exist in the input, we just generate them + if (comp == TransformationComp_RotationPivotInverse || comp == TransformationComp_ScalingPivotInverse) { + chain[i] = node_property_map.end(); + continue; + } + + chain[i] = node_property_map.find(NameTransformationCompProperty(comp)); + if (chain[i] != node_property_map.end()) { + + // check if this curves contains redundant information by looking + // up the corresponding node's transformation chain. + if (doc.Settings().optimizeEmptyAnimationCurves && + IsRedundantAnimationData(target, comp, (*chain[i]).second)) { + + FBXImporter::LogDebug("dropping redundant animation channel for node " + target.Name()); + continue; + } + + has_any = true; + + if (comp != TransformationComp_Rotation && comp != TransformationComp_Scaling && comp != TransformationComp_Translation && + comp != TransformationComp_GeometricScaling && comp != TransformationComp_GeometricRotation && comp != TransformationComp_GeometricTranslation ) + { + has_complex = true; + } + } + } + + if (!has_any) { + FBXImporter::LogWarn("ignoring node animation, did not find any transformation key frames"); + return; + } + + // this needs to play nicely with GenerateTransformationNodeChain() which will + // be invoked _later_ (animations come first). If this node has only rotation, + // scaling and translation _and_ there are no animated other components either, + // we can use a single node and also a single node animation channel. + if (!has_complex && !NeedsComplexTransformationChain(target)) { + + aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain, + node_property_map.end(), + layer_map, + max_time, + min_time, + true // input is TRS order, assimp is SRT + ); + + ai_assert(nd); + node_anims.push_back(nd); + return; + } + + // otherwise, things get gruesome and we need separate animation channels + // for each part of the transformation chain. Remember which channels + // we generated and pass this information to the node conversion + // code to avoid nodes that have identity transform, but non-identity + // animations, being dropped. + unsigned int flags = 0, bit = 0x1; + for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) { + const TransformationComp comp = static_cast<TransformationComp>(i); + + if (chain[i] != node_property_map.end()) { + flags |= bit; + + ai_assert(comp != TransformationComp_RotationPivotInverse); + ai_assert(comp != TransformationComp_ScalingPivotInverse); + + const std::string& chain_name = NameTransformationChainNode(fixed_name, comp); + + aiNodeAnim* na; + switch(comp) + { + case TransformationComp_Rotation: + case TransformationComp_PreRotation: + case TransformationComp_PostRotation: + case TransformationComp_GeometricRotation: + na = GenerateRotationNodeAnim(chain_name, + target, + (*chain[i]).second, + layer_map, + max_time, + min_time); + + break; + + case TransformationComp_RotationOffset: + case TransformationComp_RotationPivot: + case TransformationComp_ScalingOffset: + case TransformationComp_ScalingPivot: + case TransformationComp_Translation: + case TransformationComp_GeometricTranslation: + na = GenerateTranslationNodeAnim(chain_name, + target, + (*chain[i]).second, + layer_map, + max_time, + min_time); + + // pivoting requires us to generate an implicit inverse channel to undo the pivot translation + if (comp == TransformationComp_RotationPivot) { + const std::string& invName = NameTransformationChainNode(fixed_name, + TransformationComp_RotationPivotInverse); + + aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName, + target, + (*chain[i]).second, + layer_map, + max_time, + min_time, + true); + + ai_assert(inv); + node_anims.push_back(inv); + + ai_assert(TransformationComp_RotationPivotInverse > i); + flags |= bit << (TransformationComp_RotationPivotInverse - i); + } + else if (comp == TransformationComp_ScalingPivot) { + const std::string& invName = NameTransformationChainNode(fixed_name, + TransformationComp_ScalingPivotInverse); + + aiNodeAnim* const inv = GenerateTranslationNodeAnim(invName, + target, + (*chain[i]).second, + layer_map, + max_time, + min_time, + true); + + ai_assert(inv); + node_anims.push_back(inv); + + ai_assert(TransformationComp_RotationPivotInverse > i); + flags |= bit << (TransformationComp_RotationPivotInverse - i); + } + + break; + + case TransformationComp_Scaling: + case TransformationComp_GeometricScaling: + na = GenerateScalingNodeAnim(chain_name, + target, + (*chain[i]).second, + layer_map, + max_time, + min_time); + + break; + + default: + ai_assert(false); + } + + ai_assert(na); + node_anims.push_back(na); + continue; + } + } + + node_anim_chain_bits[fixed_name] = flags; + } + + + // ------------------------------------------------------------------------------------------------ + bool IsRedundantAnimationData(const Model& target, + TransformationComp comp, + const std::vector<const AnimationCurveNode*>& curves) + { + ai_assert(curves.size()); + + // look for animation nodes with + // * sub channels for all relevant components set + // * one key/value pair per component + // * combined values match up the corresponding value in the bind pose node transformation + // only such nodes are 'redundant' for this function. + + if (curves.size() > 1) { + return false; + } + + const AnimationCurveNode& nd = *curves.front(); + const AnimationCurveMap& sub_curves = nd.Curves(); + + const AnimationCurveMap::const_iterator dx = sub_curves.find("d|X"); + const AnimationCurveMap::const_iterator dy = sub_curves.find("d|Y"); + const AnimationCurveMap::const_iterator dz = sub_curves.find("d|Z"); + + if (dx == sub_curves.end() || dy == sub_curves.end() || dz == sub_curves.end()) { + return false; + } + + const KeyValueList& vx = (*dx).second->GetValues(); + const KeyValueList& vy = (*dy).second->GetValues(); + const KeyValueList& vz = (*dz).second->GetValues(); + + if(vx.size() != 1 || vy.size() != 1 || vz.size() != 1) { + return false; + } + + const aiVector3D dyn_val = aiVector3D(vx[0], vy[0], vz[0]); + const aiVector3D& static_val = PropertyGet<aiVector3D>(target.Props(), + NameTransformationCompProperty(comp), + TransformationCompDefaultValue(comp) + ); + + const float epsilon = 1e-6f; + return (dyn_val - static_val).SquareLength() < epsilon; + } + + + // ------------------------------------------------------------------------------------------------ + aiNodeAnim* GenerateRotationNodeAnim(const std::string& name, + const Model& target, + const std::vector<const AnimationCurveNode*>& curves, + const LayerMap& layer_map, + double& max_time, + double& min_time) + { + ScopeGuard<aiNodeAnim> na(new aiNodeAnim()); + na->mNodeName.Set(name); + + ConvertRotationKeys(na, curves, layer_map, max_time,min_time, target.RotationOrder()); + + // dummy scaling key + na->mScalingKeys = new aiVectorKey[1]; + na->mNumScalingKeys = 1; + + na->mScalingKeys[0].mTime = 0.; + na->mScalingKeys[0].mValue = aiVector3D(1.0f,1.0f,1.0f); + + // dummy position key + na->mPositionKeys = new aiVectorKey[1]; + na->mNumPositionKeys = 1; + + na->mPositionKeys[0].mTime = 0.; + na->mPositionKeys[0].mValue = aiVector3D(); + + return na.dismiss(); + } + + + // ------------------------------------------------------------------------------------------------ + aiNodeAnim* GenerateScalingNodeAnim(const std::string& name, + const Model& target, + const std::vector<const AnimationCurveNode*>& curves, + const LayerMap& layer_map, + double& max_time, + double& min_time) + { + ScopeGuard<aiNodeAnim> na(new aiNodeAnim()); + na->mNodeName.Set(name); + + ConvertScaleKeys(na, curves, layer_map, max_time,min_time); + + // dummy rotation key + na->mRotationKeys = new aiQuatKey[1]; + na->mNumRotationKeys = 1; + + na->mRotationKeys[0].mTime = 0.; + na->mRotationKeys[0].mValue = aiQuaternion(); + + // dummy position key + na->mPositionKeys = new aiVectorKey[1]; + na->mNumPositionKeys = 1; + + na->mPositionKeys[0].mTime = 0.; + na->mPositionKeys[0].mValue = aiVector3D(); + + return na.dismiss(); + } + + + // ------------------------------------------------------------------------------------------------ + aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name, + const Model& target, + const std::vector<const AnimationCurveNode*>& curves, + const LayerMap& layer_map, + double& max_time, + double& min_time, + bool inverse = false) + { + ScopeGuard<aiNodeAnim> na(new aiNodeAnim()); + na->mNodeName.Set(name); + + ConvertTranslationKeys(na, curves, layer_map, max_time,min_time); + + if (inverse) { + for (unsigned int i = 0; i < na->mNumPositionKeys; ++i) { + na->mPositionKeys[i].mValue *= -1.0f; + } + } + + // dummy scaling key + na->mScalingKeys = new aiVectorKey[1]; + na->mNumScalingKeys = 1; + + na->mScalingKeys[0].mTime = 0.; + na->mScalingKeys[0].mValue = aiVector3D(1.0f,1.0f,1.0f); + + // dummy rotation key + na->mRotationKeys = new aiQuatKey[1]; + na->mNumRotationKeys = 1; + + na->mRotationKeys[0].mTime = 0.; + na->mRotationKeys[0].mValue = aiQuaternion(); + + return na.dismiss(); + } + + + // ------------------------------------------------------------------------------------------------ + // generate node anim, extracting only Rotation, Scaling and Translation from the given chain + aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name, + const Model& target, + NodeMap::const_iterator chain[TransformationComp_MAXIMUM], + NodeMap::const_iterator iter_end, + const LayerMap& layer_map, + double& max_time, + double& min_time, + bool reverse_order = false) + + { + ScopeGuard<aiNodeAnim> na(new aiNodeAnim()); + na->mNodeName.Set(name); + + const PropertyTable& props = target.Props(); + + // need to convert from TRS order to SRT? + if(reverse_order) { + + aiVector3D def_scale, def_translate; + aiQuaternion def_rot; + + KeyFrameListList scaling; + KeyFrameListList translation; + KeyFrameListList rotation; + + if(chain[TransformationComp_Scaling] != iter_end) { + scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second); + } + else { + def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f)); + } + + if(chain[TransformationComp_Translation] != iter_end) { + translation = GetKeyframeList((*chain[TransformationComp_Translation]).second); + } + else { + def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f)); + } + + if(chain[TransformationComp_Rotation] != iter_end) { + rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second); + } + else { + def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)), + target.RotationOrder()); + } + + KeyFrameListList joined; + joined.insert(joined.end(), scaling.begin(), scaling.end()); + joined.insert(joined.end(), translation.begin(), translation.end()); + joined.insert(joined.end(), rotation.begin(), rotation.end()); + + const KeyTimeList& times = GetKeyTimeList(joined); + + aiQuatKey* out_quat = new aiQuatKey[times.size()]; + aiVectorKey* out_scale = new aiVectorKey[times.size()]; + aiVectorKey* out_translation = new aiVectorKey[times.size()]; + + ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation, + scaling, + translation, + rotation, + times, + max_time, + min_time, + target.RotationOrder(), + def_scale, + def_translate, + def_rot); + + // XXX remove duplicates / redundant keys which this operation did + // likely produce if not all three channels were equally dense. + + na->mNumScalingKeys = static_cast<unsigned int>(times.size()); + na->mNumRotationKeys = na->mNumScalingKeys; + na->mNumPositionKeys = na->mNumScalingKeys; + + na->mScalingKeys = out_scale; + na->mRotationKeys = out_quat; + na->mPositionKeys = out_translation; + } + else { + + // if a particular transformation is not given, grab it from + // the corresponding node to meet the semantics of aiNodeAnim, + // which requires all of rotation, scaling and translation + // to be set. + if(chain[TransformationComp_Scaling] != iter_end) { + ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second, + layer_map, + max_time, + min_time); + } + else { + na->mScalingKeys = new aiVectorKey[1]; + na->mNumScalingKeys = 1; + + na->mScalingKeys[0].mTime = 0.; + na->mScalingKeys[0].mValue = PropertyGet(props,"Lcl Scaling", + aiVector3D(1.f,1.f,1.f)); + } + + if(chain[TransformationComp_Rotation] != iter_end) { + ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second, + layer_map, + max_time, + min_time, + target.RotationOrder()); + } + else { + na->mRotationKeys = new aiQuatKey[1]; + na->mNumRotationKeys = 1; + + na->mRotationKeys[0].mTime = 0.; + na->mRotationKeys[0].mValue = EulerToQuaternion( + PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)), + target.RotationOrder()); + } + + if(chain[TransformationComp_Translation] != iter_end) { + ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second, + layer_map, + max_time, + min_time); + } + else { + na->mPositionKeys = new aiVectorKey[1]; + na->mNumPositionKeys = 1; + + na->mPositionKeys[0].mTime = 0.; + na->mPositionKeys[0].mValue = PropertyGet(props,"Lcl Translation", + aiVector3D(0.f,0.f,0.f)); + } + + } + return na.dismiss(); + } + + + + // key (time), value, mapto (component index) + typedef boost::tuple< const KeyTimeList*, const KeyValueList*, unsigned int > KeyFrameList; + typedef std::vector<KeyFrameList> KeyFrameListList; + + + + // ------------------------------------------------------------------------------------------------ + KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes) + { + KeyFrameListList inputs; + inputs.reserve(nodes.size()*3); + + BOOST_FOREACH(const AnimationCurveNode* node, nodes) { + ai_assert(node); + + const AnimationCurveMap& curves = node->Curves(); + BOOST_FOREACH(const AnimationCurveMap::value_type& kv, curves) { + + unsigned int mapto; + if (kv.first == "d|X") { + mapto = 0; + } + else if (kv.first == "d|Y") { + mapto = 1; + } + else if (kv.first == "d|Z") { + mapto = 2; + } + else { + FBXImporter::LogWarn("ignoring scale animation curve, did not recognize target component"); + continue; + } + + const AnimationCurve* const curve = kv.second; + ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size()); + + inputs.push_back(boost::make_tuple(&curve->GetKeys(), &curve->GetValues(), mapto)); + } + } + return inputs; // pray for NRVO :-) + } + + + // ------------------------------------------------------------------------------------------------ + KeyTimeList GetKeyTimeList(const KeyFrameListList& inputs) + { + ai_assert(inputs.size()); + + // reserve some space upfront - it is likely that the keyframe lists + // have matching time values, so max(of all keyframe lists) should + // be a good estimate. + KeyTimeList keys; + + size_t estimate = 0; + BOOST_FOREACH(const KeyFrameList& kfl, inputs) { + estimate = std::max(estimate, kfl.get<0>()->size()); + } + + keys.reserve(estimate); + + std::vector<unsigned int> next_pos; + next_pos.resize(inputs.size(),0); + + const size_t count = inputs.size(); + while(true) { + + uint64_t min_tick = std::numeric_limits<uint64_t>::max(); + for (size_t i = 0; i < count; ++i) { + const KeyFrameList& kfl = inputs[i]; + + if (kfl.get<0>()->size() > next_pos[i] && kfl.get<0>()->at(next_pos[i]) < min_tick) { + min_tick = kfl.get<0>()->at(next_pos[i]); + } + } + + if (min_tick == std::numeric_limits<uint64_t>::max()) { + break; + } + keys.push_back(min_tick); + + for (size_t i = 0; i < count; ++i) { + const KeyFrameList& kfl = inputs[i]; + + + while(kfl.get<0>()->size() > next_pos[i] && kfl.get<0>()->at(next_pos[i]) == min_tick) { + ++next_pos[i]; + } + } + } + + return keys; + } + + + // ------------------------------------------------------------------------------------------------ + void InterpolateKeys(aiVectorKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs, + const bool geom, + double& max_time, + double& min_time) + + { + ai_assert(keys.size()); + ai_assert(valOut); + + std::vector<unsigned int> next_pos; + const size_t count = inputs.size(); + + next_pos.resize(inputs.size(),0); + + BOOST_FOREACH(KeyTimeList::value_type time, keys) { + float result[3] = {0.0f, 0.0f, 0.0f}; + if(geom) { + result[0] = result[1] = result[2] = 1.0f; + } + + for (size_t i = 0; i < count; ++i) { + const KeyFrameList& kfl = inputs[i]; + + const size_t ksize = kfl.get<0>()->size(); + if (ksize > next_pos[i] && kfl.get<0>()->at(next_pos[i]) == time) { + ++next_pos[i]; + } + + const size_t id0 = next_pos[i]>0 ? next_pos[i]-1 : 0; + const size_t id1 = next_pos[i]==ksize ? ksize-1 : next_pos[i]; + + // use lerp for interpolation + const KeyValueList::value_type valueA = kfl.get<1>()->at(id0); + const KeyValueList::value_type valueB = kfl.get<1>()->at(id1); + + const KeyTimeList::value_type timeA = kfl.get<0>()->at(id0); + const KeyTimeList::value_type timeB = kfl.get<0>()->at(id1); + + // do the actual interpolation in double-precision arithmetics + // because it is a bit sensitive to rounding errors. + const double factor = timeB == timeA ? 0. : static_cast<double>((time - timeA) / (timeB - timeA)); + const float interpValue = static_cast<float>(valueA + (valueB - valueA) * factor); + + if(geom) { + result[kfl.get<2>()] *= interpValue; + } + else { + result[kfl.get<2>()] += interpValue; + } + } + + // magic value to convert fbx times to seconds + valOut->mTime = CONVERT_FBX_TIME(time) * anim_fps; + + min_time = std::min(min_time, valOut->mTime); + max_time = std::max(max_time, valOut->mTime); + + valOut->mValue.x = result[0]; + valOut->mValue.y = result[1]; + valOut->mValue.z = result[2]; + + ++valOut; + } + } + + + // ------------------------------------------------------------------------------------------------ + void InterpolateKeys(aiQuatKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs, + const bool geom, + double& maxTime, + double& minTime, + Model::RotOrder order) + { + ai_assert(keys.size()); + ai_assert(valOut); + + boost::scoped_array<aiVectorKey> temp(new aiVectorKey[keys.size()]); + InterpolateKeys(temp.get(),keys,inputs,geom,maxTime, minTime); + + aiMatrix4x4 m; + + aiQuaternion lastq; + + for (size_t i = 0, c = keys.size(); i < c; ++i) { + + valOut[i].mTime = temp[i].mTime; + + + GetRotationMatrix(order, temp[i].mValue, m); + aiQuaternion quat = aiQuaternion(aiMatrix3x3(m)); + + // take shortest path by checking the inner product + // http://www.3dkingdoms.com/weekly/weekly.php?a=36 + if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) + { + quat.x = -quat.x; + quat.y = -quat.y; + quat.z = -quat.z; + quat.w = -quat.w; + } + lastq = quat; + + valOut[i].mValue = quat; + } + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale, + aiVectorKey* out_translation, + const KeyFrameListList& scaling, + const KeyFrameListList& translation, + const KeyFrameListList& rotation, + const KeyTimeList& times, + double& maxTime, + double& minTime, + Model::RotOrder order, + const aiVector3D& def_scale, + const aiVector3D& def_translate, + const aiQuaternion& def_rotation) + { + if (rotation.size()) { + InterpolateKeys(out_quat, times, rotation, false, maxTime, minTime, order); + } + else { + for (size_t i = 0; i < times.size(); ++i) { + out_quat[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps; + out_quat[i].mValue = def_rotation; + } + } + + if (scaling.size()) { + InterpolateKeys(out_scale, times, scaling, true, maxTime, minTime); + } + else { + for (size_t i = 0; i < times.size(); ++i) { + out_scale[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps; + out_scale[i].mValue = def_scale; + } + } + + if (translation.size()) { + InterpolateKeys(out_translation, times, translation, false, maxTime, minTime); + } + else { + for (size_t i = 0; i < times.size(); ++i) { + out_translation[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps; + out_translation[i].mValue = def_translate; + } + } + + const size_t count = times.size(); + for (size_t i = 0; i < count; ++i) { + aiQuaternion& r = out_quat[i].mValue; + aiVector3D& s = out_scale[i].mValue; + aiVector3D& t = out_translation[i].mValue; + + aiMatrix4x4 mat, temp; + aiMatrix4x4::Translation(t, mat); + mat *= aiMatrix4x4( r.GetMatrix() ); + mat *= aiMatrix4x4::Scaling(s, temp); + + mat.Decompose(s, r, t); + } + } + + + // ------------------------------------------------------------------------------------------------ + // euler xyz -> quat + aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order) + { + aiMatrix4x4 m; + GetRotationMatrix(order, rot, m); + + return aiQuaternion(aiMatrix3x3(m)); + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& layers, + double& maxTime, + double& minTime) + { + ai_assert(nodes.size()); + + // XXX for now, assume scale should be blended geometrically (i.e. two + // layers should be multiplied with each other). There is a FBX + // property in the layer to specify the behaviour, though. + + const KeyFrameListList& inputs = GetKeyframeList(nodes); + const KeyTimeList& keys = GetKeyTimeList(inputs); + + na->mNumScalingKeys = static_cast<unsigned int>(keys.size()); + na->mScalingKeys = new aiVectorKey[keys.size()]; + InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime); + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, + const LayerMap& layers, + double& maxTime, + double& minTime) + { + ai_assert(nodes.size()); + + // XXX see notes in ConvertScaleKeys() + const KeyFrameListList& inputs = GetKeyframeList(nodes); + const KeyTimeList& keys = GetKeyTimeList(inputs); + + na->mNumPositionKeys = static_cast<unsigned int>(keys.size()); + na->mPositionKeys = new aiVectorKey[keys.size()]; + InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime); + } + + + // ------------------------------------------------------------------------------------------------ + void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, + const LayerMap& layers, + double& maxTime, + double& minTime, + Model::RotOrder order) + { + ai_assert(nodes.size()); + + // XXX see notes in ConvertScaleKeys() + const std::vector< KeyFrameList >& inputs = GetKeyframeList(nodes); + const KeyTimeList& keys = GetKeyTimeList(inputs); + + na->mNumRotationKeys = static_cast<unsigned int>(keys.size()); + na->mRotationKeys = new aiQuatKey[keys.size()]; + InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order); + } + + + // ------------------------------------------------------------------------------------------------ + // copy generated meshes, animations, lights, cameras and textures to the output scene + void TransferDataToScene() + { + ai_assert(!out->mMeshes && !out->mNumMeshes); + + // note: the trailing () ensures initialization with NULL - not + // many C++ users seem to know this, so pointing it out to avoid + // confusion why this code works. + + if(meshes.size()) { + out->mMeshes = new aiMesh*[meshes.size()](); + out->mNumMeshes = static_cast<unsigned int>(meshes.size()); + + std::swap_ranges(meshes.begin(),meshes.end(),out->mMeshes); + } + + if(materials.size()) { + out->mMaterials = new aiMaterial*[materials.size()](); + out->mNumMaterials = static_cast<unsigned int>(materials.size()); + + std::swap_ranges(materials.begin(),materials.end(),out->mMaterials); + } + + if(animations.size()) { + out->mAnimations = new aiAnimation*[animations.size()](); + out->mNumAnimations = static_cast<unsigned int>(animations.size()); + + std::swap_ranges(animations.begin(),animations.end(),out->mAnimations); + } + + if(lights.size()) { + out->mLights = new aiLight*[lights.size()](); + out->mNumLights = static_cast<unsigned int>(lights.size()); + + std::swap_ranges(lights.begin(),lights.end(),out->mLights); + } + + if(cameras.size()) { + out->mCameras = new aiCamera*[cameras.size()](); + out->mNumCameras = static_cast<unsigned int>(cameras.size()); + + std::swap_ranges(cameras.begin(),cameras.end(),out->mCameras); + } + } + + +private: + + // 0: not assigned yet, others: index is value - 1 + unsigned int defaultMaterialIndex; + + std::vector<aiMesh*> meshes; + std::vector<aiMaterial*> materials; + std::vector<aiAnimation*> animations; + std::vector<aiLight*> lights; + std::vector<aiCamera*> cameras; + + typedef std::map<const Material*, unsigned int> MaterialMap; + MaterialMap materials_converted; + + typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap; + MeshMap meshes_converted; + + // fixed node name -> which trafo chain components have animations? + typedef std::map<std::string, unsigned int> NodeAnimBitMap; + NodeAnimBitMap node_anim_chain_bits; + + // name -> has had its prefix_stripped? + typedef std::map<std::string, bool> NodeNameMap; + NodeNameMap node_names; + + typedef std::map<std::string, std::string> NameNameMap; + NameNameMap renamed_nodes; + + double anim_fps; + + aiScene* const out; + const FBX::Document& doc; +}; + +//} // !anon + +// ------------------------------------------------------------------------------------------------ +void ConvertToAssimpScene(aiScene* out, const Document& doc) +{ + Converter converter(out,doc); +} + +} // !FBX +} // !Assimp + +#endif diff --git a/src/3rdparty/assimp/code/FBXConverter.h b/src/3rdparty/assimp/code/FBXConverter.h new file mode 100644 index 000000000..0585bf5cf --- /dev/null +++ b/src/3rdparty/assimp/code/FBXConverter.h @@ -0,0 +1,63 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXDConverter.h + * @brief FBX DOM to aiScene conversion + */ +#ifndef INCLUDED_AI_FBX_CONVERTER_H +#define INCLUDED_AI_FBX_CONVERTER_H + +namespace Assimp { +namespace FBX { + + class Document; + + +/** Convert a FBX #Document to #aiScene + * @param out Empty scene to be populated + * @param doc Parsed FBX document */ +void ConvertToAssimpScene(aiScene* out, const Document& doc); + + +} +} + + +#endif diff --git a/src/3rdparty/assimp/code/FBXDeformer.cpp b/src/3rdparty/assimp/code/FBXDeformer.cpp new file mode 100644 index 000000000..22e8aa25b --- /dev/null +++ b/src/3rdparty/assimp/code/FBXDeformer.cpp @@ -0,0 +1,169 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXNoteAttribute.cpp + * @brief Assimp::FBX::NodeAttribute (and subclasses) implementation + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXImporter.h" +#include "FBXImportSettings.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + +// ------------------------------------------------------------------------------------------------ +Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name) + : Object(id,element,name) +{ + const Scope& sc = GetRequiredScope(element); + + const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2)); + props = GetPropertyTable(doc,"Deformer.Fbx" + classname,element,sc,true); +} + + +// ------------------------------------------------------------------------------------------------ +Deformer::~Deformer() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: Deformer(id,element,doc,name) +, node() +{ + const Scope& sc = GetRequiredScope(element); + + const Element* const Indexes = sc["Indexes"]; + const Element* const Weights = sc["Weights"]; + + const Element& Transform = GetRequiredElement(sc,"Transform",&element); + const Element& TransformLink = GetRequiredElement(sc,"TransformLink",&element); + + transform = ReadMatrix(Transform); + transformLink = ReadMatrix(TransformLink); + + // it is actually possible that there be Deformer's with no weights + if (!!Indexes != !!Weights) { + DOMError("either Indexes or Weights are missing from Cluster",&element); + } + + if(Indexes) { + ParseVectorDataArray(indices,*Indexes); + ParseVectorDataArray(weights,*Weights); + } + + if(indices.size() != weights.size()) { + DOMError("sizes of index and weight array don't match up",&element); + } + + // read assigned node + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Model"); + BOOST_FOREACH(const Connection* con, conns) { + const Model* const mod = ProcessSimpleConnection<Model>(*con, false, "Model -> Cluster", element); + if(mod) { + node = mod; + break; + } + } + + if (!node) { + DOMError("failed to read target Node for Cluster",&element); + } +} + + +// ------------------------------------------------------------------------------------------------ +Cluster::~Cluster() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: Deformer(id,element,doc,name) +{ + const Scope& sc = GetRequiredScope(element); + + const Element* const Link_DeformAcuracy = sc["Link_DeformAcuracy"]; + if(Link_DeformAcuracy) { + accuracy = ParseTokenAsFloat(GetRequiredToken(*Link_DeformAcuracy,0)); + } + + // resolve assigned clusters + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer"); + + clusters.reserve(conns.size()); + BOOST_FOREACH(const Connection* con, conns) { + + const Cluster* const cluster = ProcessSimpleConnection<Cluster>(*con, false, "Cluster -> Skin", element); + if(cluster) { + clusters.push_back(cluster); + continue; + } + } +} + + +// ------------------------------------------------------------------------------------------------ +Skin::~Skin() +{ + +} + + + +} +} + +#endif + diff --git a/src/3rdparty/assimp/code/FBXDocument.cpp b/src/3rdparty/assimp/code/FBXDocument.cpp new file mode 100644 index 000000000..404a8d6e2 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXDocument.cpp @@ -0,0 +1,721 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the* + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXDocument.cpp + * @brief Implementation of the FBX DOM classes + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include <functional> + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXUtil.h" +#include "FBXImporter.h" +#include "FBXImportSettings.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + +using namespace Util; + +// ------------------------------------------------------------------------------------------------ +LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc) +: doc(doc) +, element(element) +, id(id) +, flags() +{ + +} + +// ------------------------------------------------------------------------------------------------ +LazyObject::~LazyObject() +{ + +} + +// ------------------------------------------------------------------------------------------------ +const Object* LazyObject::Get(bool dieOnError) +{ + if(IsBeingConstructed() || FailedToConstruct()) { + return NULL; + } + + if (object.get()) { + return object.get(); + } + + // if this is the root object, we return a dummy since there + // is no root object int he fbx file - it is just referenced + // with id 0. + if(id == 0L) { + object.reset(new Object(id, element, "Model::RootNode")); + return object.get(); + } + + const Token& key = element.KeyToken(); + const TokenList& tokens = element.Tokens(); + + if(tokens.size() < 3) { + DOMError("expected at least 3 tokens: id, name and class tag",&element); + } + + const char* err; + std::string name = ParseTokenAsString(*tokens[1],err); + if (err) { + DOMError(err,&element); + } + + // small fix for binary reading: binary fbx files don't use + // prefixes such as Model:: in front of their names. The + // loading code expects this at many places, though! + // so convert the binary representation (a 0x0001) to the + // double colon notation. + if(tokens[1]->IsBinary()) { + for (size_t i = 0; i < name.length(); ++i) { + if (name[i] == 0x0 && name[i+1] == 0x1) { + name = name.substr(i+2) + "::" + name.substr(0,i); + } + } + } + + const std::string classtag = ParseTokenAsString(*tokens[2],err); + if (err) { + DOMError(err,&element); + } + + // prevent recursive calls + flags |= BEING_CONSTRUCTED; + + try { + // this needs to be relatively fast since it happens a lot, + // so avoid constructing strings all the time. + const char* obtype = key.begin(); + const size_t length = static_cast<size_t>(key.end()-key.begin()); + if (!strncmp(obtype,"Geometry",length)) { + if (!strcmp(classtag.c_str(),"Mesh")) { + object.reset(new MeshGeometry(id,element,name,doc)); + } + } + else if (!strncmp(obtype,"NodeAttribute",length)) { + if (!strcmp(classtag.c_str(),"Camera")) { + object.reset(new Camera(id,element,doc,name)); + } + else if (!strcmp(classtag.c_str(),"CameraSwitcher")) { + object.reset(new CameraSwitcher(id,element,doc,name)); + } + else if (!strcmp(classtag.c_str(),"Light")) { + object.reset(new Light(id,element,doc,name)); + } + else if (!strcmp(classtag.c_str(),"Null")) { + object.reset(new Null(id,element,doc,name)); + } + else if (!strcmp(classtag.c_str(),"LimbNode")) { + object.reset(new LimbNode(id,element,doc,name)); + } + } + else if (!strncmp(obtype,"Deformer",length)) { + if (!strcmp(classtag.c_str(),"Cluster")) { + object.reset(new Cluster(id,element,doc,name)); + } + else if (!strcmp(classtag.c_str(),"Skin")) { + object.reset(new Skin(id,element,doc,name)); + } + } + else if (!strncmp(obtype,"Model",length)) { + // FK and IK effectors are not supported + if (strcmp(classtag.c_str(),"IKEffector") && strcmp(classtag.c_str(),"FKEffector")) { + object.reset(new Model(id,element,doc,name)); + } + } + else if (!strncmp(obtype,"Material",length)) { + object.reset(new Material(id,element,doc,name)); + } + else if (!strncmp(obtype,"Texture",length)) { + object.reset(new Texture(id,element,doc,name)); + } + else if (!strncmp(obtype,"LayeredTexture",length)) { + object.reset(new LayeredTexture(id,element,doc,name)); + } + else if (!strncmp(obtype,"AnimationStack",length)) { + object.reset(new AnimationStack(id,element,name,doc)); + } + else if (!strncmp(obtype,"AnimationLayer",length)) { + object.reset(new AnimationLayer(id,element,name,doc)); + } + // note: order matters for these two + else if (!strncmp(obtype,"AnimationCurve",length)) { + object.reset(new AnimationCurve(id,element,name,doc)); + } + else if (!strncmp(obtype,"AnimationCurveNode",length)) { + object.reset(new AnimationCurveNode(id,element,name,doc)); + } + } + catch(std::exception& ex) { + flags &= ~BEING_CONSTRUCTED; + flags |= FAILED_TO_CONSTRUCT; + + if(dieOnError || doc.Settings().strictMode) { + throw; + } + + // note: the error message is already formatted, so raw logging is ok + if(!DefaultLogger::isNullLogger()) { + DefaultLogger::get()->error(ex.what()); + } + return NULL; + } + + if (!object.get()) { + //DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element); + } + + flags &= ~BEING_CONSTRUCTED; + return object.get(); +} + +// ------------------------------------------------------------------------------------------------ +Object::Object(uint64_t id, const Element& element, const std::string& name) +: element(element) +, name(name) +, id(id) +{ + +} + +// ------------------------------------------------------------------------------------------------ +Object::~Object() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +FileGlobalSettings::FileGlobalSettings(const Document& doc, boost::shared_ptr<const PropertyTable> props) +: props(props) +, doc(doc) +{ + +} + + +// ------------------------------------------------------------------------------------------------ +FileGlobalSettings::~FileGlobalSettings() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +Document::Document(const Parser& parser, const ImportSettings& settings) +: settings(settings) +, parser(parser) +{ + // cannot use array default initialization syntax because vc8 fails on it + for (unsigned int i = 0; i < 7; ++i) { + creationTimeStamp[i] = 0; + } + + ReadHeader(); + ReadPropertyTemplates(); + + ReadGlobalSettings(); + + // this order is important, connections need parsed objects to check + // whether connections are ok or not. Objects may not be evaluated yet, + // though, since this may require valid connections. + ReadObjects(); + ReadConnections(); +} + + +// ------------------------------------------------------------------------------------------------ +Document::~Document() +{ + BOOST_FOREACH(ObjectMap::value_type& v, objects) { + delete v.second; + } +} + + +// ------------------------------------------------------------------------------------------------ +void Document::ReadHeader() +{ + // read ID objects from "Objects" section + const Scope& sc = parser.GetRootScope(); + const Element* const ehead = sc["FBXHeaderExtension"]; + if(!ehead || !ehead->Compound()) { + DOMError("no FBXHeaderExtension dictionary found"); + } + + const Scope& shead = *ehead->Compound(); + fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0)); + + // while we maye have some success with newer files, we don't support + // the older 6.n fbx format + if(fbxVersion < 7100) { + DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013"); + } + if(fbxVersion > 7300) { + if(Settings().strictMode) { + DOMError("unsupported, newer format version, supported are only FBX 2011, FBX 2012 and FBX 2013" + " (turn off strict mode to try anyhow) "); + } + else { + DOMWarning("unsupported, newer format version, supported are only FBX 2011, FBX 2012 and FBX 2013," + " trying to read it nevertheless"); + } + } + + + const Element* const ecreator = shead["Creator"]; + if(ecreator) { + creator = ParseTokenAsString(GetRequiredToken(*ecreator,0)); + } + + const Element* const etimestamp = shead["CreationTimeStamp"]; + if(etimestamp && etimestamp->Compound()) { + const Scope& stimestamp = *etimestamp->Compound(); + creationTimeStamp[0] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Year"),0)); + creationTimeStamp[1] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Month"),0)); + creationTimeStamp[2] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Day"),0)); + creationTimeStamp[3] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Hour"),0)); + creationTimeStamp[4] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Minute"),0)); + creationTimeStamp[5] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Second"),0)); + creationTimeStamp[6] = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(stimestamp,"Millisecond"),0)); + } +} + +// ------------------------------------------------------------------------------------------------ +void Document::ReadGlobalSettings() +{ + const Scope& sc = parser.GetRootScope(); + const Element* const ehead = sc["GlobalSettings"]; + if(!ehead || !ehead->Compound()) { + DOMWarning("no GlobalSettings dictionary found"); + + globals.reset(new FileGlobalSettings(*this, boost::make_shared<const PropertyTable>())); + return; + } + + boost::shared_ptr<const PropertyTable> props = GetPropertyTable(*this, "", *ehead, *ehead->Compound(), true); + + if(!props) { + DOMError("GlobalSettings dictionary contains no property table"); + } + + globals.reset(new FileGlobalSettings(*this, props)); +} + + +// ------------------------------------------------------------------------------------------------ +void Document::ReadObjects() +{ + // read ID objects from "Objects" section + const Scope& sc = parser.GetRootScope(); + const Element* const eobjects = sc["Objects"]; + if(!eobjects || !eobjects->Compound()) { + DOMError("no Objects dictionary found"); + } + + // add a dummy entry to represent the Model::RootNode object (id 0), + // which is only indirectly defined in the input file + objects[0] = new LazyObject(0L, *eobjects, *this); + + const Scope& sobjects = *eobjects->Compound(); + BOOST_FOREACH(const ElementMap::value_type& el, sobjects.Elements()) { + + // extract ID + const TokenList& tok = el.second->Tokens(); + + if (tok.empty()) { + DOMError("expected ID after object key",el.second); + } + + const char* err; + + const uint64_t id = ParseTokenAsID(*tok[0], err); + if(err) { + DOMError(err,el.second); + } + + // id=0 is normally implicit + if(id == 0L) { + DOMError("encountered object with implicitly defined id 0",el.second); + } + + if(objects.find(id) != objects.end()) { + DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second); + } + + objects[id] = new LazyObject(id, *el.second, *this); + + // grab all animation stacks upfront since there is no listing of them + if(!strcmp(el.first.c_str(),"AnimationStack")) { + animationStacks.push_back(id); + } + } +} + + +// ------------------------------------------------------------------------------------------------ +void Document::ReadPropertyTemplates() +{ + const Scope& sc = parser.GetRootScope(); + // read property templates from "Definitions" section + const Element* const edefs = sc["Definitions"]; + if(!edefs || !edefs->Compound()) { + DOMWarning("no Definitions dictionary found"); + return; + } + + const Scope& sdefs = *edefs->Compound(); + const ElementCollection otypes = sdefs.GetCollection("ObjectType"); + for(ElementMap::const_iterator it = otypes.first; it != otypes.second; ++it) { + const Element& el = *(*it).second; + const Scope* sc = el.Compound(); + if(!sc) { + DOMWarning("expected nested scope in ObjectType, ignoring",&el); + continue; + } + + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + DOMWarning("expected name for ObjectType element, ignoring",&el); + continue; + } + + const std::string& oname = ParseTokenAsString(*tok[0]); + + const ElementCollection templs = sc->GetCollection("PropertyTemplate"); + for(ElementMap::const_iterator it = templs.first; it != templs.second; ++it) { + const Element& el = *(*it).second; + const Scope* sc = el.Compound(); + if(!sc) { + DOMWarning("expected nested scope in PropertyTemplate, ignoring",&el); + continue; + } + + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + DOMWarning("expected name for PropertyTemplate element, ignoring",&el); + continue; + } + + const std::string& pname = ParseTokenAsString(*tok[0]); + + const Element* Properties70 = (*sc)["Properties70"]; + if(Properties70) { + boost::shared_ptr<const PropertyTable> props = boost::make_shared<const PropertyTable>( + *Properties70,boost::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL)) + ); + + templates[oname+"."+pname] = props; + } + } + } +} + + + +// ------------------------------------------------------------------------------------------------ +void Document::ReadConnections() +{ + const Scope& sc = parser.GetRootScope(); + // read property templates from "Definitions" section + const Element* const econns = sc["Connections"]; + if(!econns || !econns->Compound()) { + DOMError("no Connections dictionary found"); + } + + uint64_t insertionOrder = 0l; + + const Scope& sconns = *econns->Compound(); + const ElementCollection conns = sconns.GetCollection("C"); + for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) { + const Element& el = *(*it).second; + const std::string& type = ParseTokenAsString(GetRequiredToken(el,0)); + const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1)); + const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2)); + + // OO = object-object connection + // OP = object-property connection, in which case the destination property follows the object ID + const std::string& prop = (type == "OP" ? ParseTokenAsString(GetRequiredToken(el,3)) : ""); + + if(objects.find(src) == objects.end()) { + DOMWarning("source object for connection does not exist",&el); + continue; + } + + // dest may be 0 (root node) but we added a dummy object before + if(objects.find(dest) == objects.end()) { + DOMWarning("destination object for connection does not exist",&el); + continue; + } + + // add new connection + const Connection* const c = new Connection(insertionOrder++,src,dest,prop,*this); + src_connections.insert(ConnectionMap::value_type(src,c)); + dest_connections.insert(ConnectionMap::value_type(dest,c)); + } +} + + +// ------------------------------------------------------------------------------------------------ +const std::vector<const AnimationStack*>& Document::AnimationStacks() const +{ + if (!animationStacksResolved.empty() || !animationStacks.size()) { + return animationStacksResolved; + } + + animationStacksResolved.reserve(animationStacks.size()); + BOOST_FOREACH(uint64_t id, animationStacks) { + LazyObject* const lazy = GetObject(id); + const AnimationStack* stack; + if(!lazy || !(stack = lazy->Get<AnimationStack>())) { + DOMWarning("failed to read AnimationStack object"); + continue; + } + animationStacksResolved.push_back(stack); + } + + return animationStacksResolved; +} + + +// ------------------------------------------------------------------------------------------------ +LazyObject* Document::GetObject(uint64_t id) const +{ + ObjectMap::const_iterator it = objects.find(id); + return it == objects.end() ? NULL : (*it).second; +} + +#define MAX_CLASSNAMES 6 + +// ------------------------------------------------------------------------------------------------ +std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, + const ConnectionMap& conns) const +{ + std::vector<const Connection*> temp; + + const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = + conns.equal_range(id); + + temp.reserve(std::distance(range.first,range.second)); + for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) { + temp.push_back((*it).second); + } + + std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare)); + + return temp; // NRVO should handle this +} + + +// ------------------------------------------------------------------------------------------------ +std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src, + const ConnectionMap& conns, + const char* const* classnames, + size_t count) const + +{ + ai_assert(classnames); + ai_assert(count != 0 && count <= MAX_CLASSNAMES); + + size_t lenghts[MAX_CLASSNAMES]; + + const size_t c = count; + for (size_t i = 0; i < c; ++i) { + lenghts[i] = strlen(classnames[i]); + } + + std::vector<const Connection*> temp; + + const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = + conns.equal_range(id); + + temp.reserve(std::distance(range.first,range.second)); + for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) { + const Token& key = (is_src + ? (*it).second->LazyDestinationObject() + : (*it).second->LazySourceObject() + ).GetElement().KeyToken(); + + const char* obtype = key.begin(); + + for (size_t i = 0; i < c; ++i) { + ai_assert(classnames[i]); + if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) { + obtype = NULL; + break; + } + } + + if(obtype) { + continue; + } + + temp.push_back((*it).second); + } + + std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare)); + return temp; // NRVO should handle this +} + + +// ------------------------------------------------------------------------------------------------ +std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const +{ + return GetConnectionsSequenced(source, ConnectionsBySource()); +} + + + +// ------------------------------------------------------------------------------------------------ +std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t dest, + const char* classname) const +{ + const char* arr[] = {classname}; + return GetConnectionsBySourceSequenced(dest, arr,1); +} + + + +// ------------------------------------------------------------------------------------------------ +std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source, + const char* const* classnames, size_t count) const +{ + return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count); +} + + +// ------------------------------------------------------------------------------------------------ +std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest, + const char* classname) const +{ + const char* arr[] = {classname}; + return GetConnectionsByDestinationSequenced(dest, arr,1); +} + + +// ------------------------------------------------------------------------------------------------ +std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest) const +{ + return GetConnectionsSequenced(dest, ConnectionsByDestination()); +} + + +// ------------------------------------------------------------------------------------------------ +std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest, + const char* const* classnames, size_t count) const + +{ + return GetConnectionsSequenced(dest, false, ConnectionsByDestination(),classnames, count); +} + + +// ------------------------------------------------------------------------------------------------ +Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, + const Document& doc) + +: insertionOrder(insertionOrder) +, prop(prop) +, src(src) +, dest(dest) +, doc(doc) +{ + ai_assert(doc.Objects().find(src) != doc.Objects().end()); + // dest may be 0 (root node) + ai_assert(!dest || doc.Objects().find(dest) != doc.Objects().end()); +} + + +// ------------------------------------------------------------------------------------------------ +Connection::~Connection() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +LazyObject& Connection::LazySourceObject() const +{ + LazyObject* const lazy = doc.GetObject(src); + ai_assert(lazy); + return *lazy; +} + + +// ------------------------------------------------------------------------------------------------ +LazyObject& Connection::LazyDestinationObject() const +{ + LazyObject* const lazy = doc.GetObject(dest); + ai_assert(lazy); + return *lazy; +} + + +// ------------------------------------------------------------------------------------------------ +const Object* Connection::SourceObject() const +{ + LazyObject* const lazy = doc.GetObject(src); + ai_assert(lazy); + return lazy->Get(); +} + + +// ------------------------------------------------------------------------------------------------ +const Object* Connection::DestinationObject() const +{ + LazyObject* const lazy = doc.GetObject(dest); + ai_assert(lazy); + return lazy->Get(); +} + +} // !FBX +} // !Assimp + +#endif + diff --git a/src/3rdparty/assimp/code/FBXDocument.h b/src/3rdparty/assimp/code/FBXDocument.h new file mode 100644 index 000000000..9dd5c79dd --- /dev/null +++ b/src/3rdparty/assimp/code/FBXDocument.h @@ -0,0 +1,1393 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXDocument.h + * @brief FBX DOM + */ +#ifndef INCLUDED_AI_FBX_DOCUMENT_H +#define INCLUDED_AI_FBX_DOCUMENT_H + +#include <vector> +#include <map> +#include <string> + +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + + class Parser; + class Object; + struct ImportSettings; + + class PropertyTable; + class Document; + class Material; + class Geometry; + + class AnimationCurve; + class AnimationCurveNode; + class AnimationLayer; + class AnimationStack; + + class Skin; + class Cluster; + + +/** Represents a delay-parsed FBX objects. Many objects in the scene + * are not needed by assimp, so it makes no sense to parse them + * upfront. */ +class LazyObject +{ +public: + + LazyObject(uint64_t id, const Element& element, const Document& doc); + ~LazyObject(); + +public: + + const Object* Get(bool dieOnError = false); + + template <typename T> + const T* Get(bool dieOnError = false) { + const Object* const ob = Get(dieOnError); + return ob ? dynamic_cast<const T*>(ob) : NULL; + } + + uint64_t ID() const { + return id; + } + + bool IsBeingConstructed() const { + return (flags & BEING_CONSTRUCTED) != 0; + } + + bool FailedToConstruct() const { + return (flags & FAILED_TO_CONSTRUCT) != 0; + } + + const Element& GetElement() const { + return element; + } + + const Document& GetDocument() const { + return doc; + } + +private: + + const Document& doc; + const Element& element; + boost::scoped_ptr<const Object> object; + + const uint64_t id; + + enum Flags { + BEING_CONSTRUCTED = 0x1, + FAILED_TO_CONSTRUCT = 0x2 + }; + + unsigned int flags; +}; + + + +/** Base class for in-memory (DOM) representations of FBX objects */ +class Object +{ +public: + + Object(uint64_t id, const Element& element, const std::string& name); + virtual ~Object(); + +public: + + const Element& SourceElement() const { + return element; + } + + const std::string& Name() const { + return name; + } + + uint64_t ID() const { + return id; + } + +protected: + const Element& element; + const std::string name; + const uint64_t id; +}; + + + +/** DOM class for generic FBX NoteAttribute blocks. NoteAttribute's just hold a property table, + * fixed members are added by deriving classes. */ +class NodeAttribute : public Object +{ +public: + + NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~NodeAttribute(); + +public: + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + +private: + + boost::shared_ptr<const PropertyTable> props; +}; + + +/** DOM base class for FBX camera settings attached to a node */ +class CameraSwitcher : public NodeAttribute +{ +public: + + CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~CameraSwitcher(); + +public: + + int CameraID() const { + return cameraId; + } + + const std::string& CameraName() const { + return cameraName; + } + + + const std::string& CameraIndexName() const { + return cameraIndexName; + } + +private: + + int cameraId; + std::string cameraName; + std::string cameraIndexName; +}; + + +#define fbx_stringize(a) #a + +#define fbx_simple_property(name, type, default_value) \ + type name() const { \ + return PropertyGet<type>(Props(), fbx_stringize(name), (default_value)); \ + } + +// XXX improve logging +#define fbx_simple_enum_property(name, type, default_value) \ + type name() const { \ + const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \ + if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \ + ai_assert(static_cast<int>(default_value) >= 0 && static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \ + return static_cast<type>(default_value); \ + } \ + return static_cast<type>(ival); \ +} + + + +/** DOM base class for FBX cameras attached to a node */ +class Camera : public NodeAttribute +{ +public: + + Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Camera(); + +public: + + fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0)); + fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0)); + fbx_simple_property(InterestPosition, aiVector3D, aiVector3D(0,0,0)); + + fbx_simple_property(AspectWidth, float, 1.0f); + fbx_simple_property(AspectHeight, float, 1.0f); + fbx_simple_property(FilmWidth, float, 1.0f); + fbx_simple_property(FilmHeight, float, 1.0f); + + fbx_simple_property(FilmAspectRatio, float, 1.0f); + fbx_simple_property(ApertureMode, int, 0); + + fbx_simple_property(FieldOfView, float, 1.0f); + fbx_simple_property(FocalLength, float, 1.0f); + +private: +}; + + +/** DOM base class for FBX null markers attached to a node */ +class Null : public NodeAttribute +{ +public: + + Null(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Null(); +}; + + +/** DOM base class for FBX limb node markers attached to a node */ +class LimbNode : public NodeAttribute +{ +public: + + LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~LimbNode(); +}; + + +/** DOM base class for FBX lights attached to a node */ +class Light : public NodeAttribute +{ +public: + + Light(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Light(); + +public: + + enum Type + { + Type_Point, + Type_Directional, + Type_Spot, + Type_Area, + Type_Volume, + + Type_MAX // end-of-enum sentinel + }; + + enum Decay + { + Decay_None, + Decay_Linear, + Decay_Quadratic, + Decay_Cubic, + + Decay_MAX // end-of-enum sentinel + }; + +public: + + fbx_simple_property(Color, aiVector3D, aiVector3D(1,1,1)); + fbx_simple_enum_property(LightType, Type, 0); + fbx_simple_property(CastLightOnObject, bool, false); + fbx_simple_property(DrawVolumetricLight, bool, true); + fbx_simple_property(DrawGroundProjection, bool, true); + fbx_simple_property(DrawFrontFacingVolumetricLight, bool, false); + fbx_simple_property(Intensity, float, 1.0f); + fbx_simple_property(InnerAngle, float, 0.0f); + fbx_simple_property(OuterAngle, float, 45.0f); + fbx_simple_property(Fog, int, 50); + fbx_simple_enum_property(DecayType, Decay, 0); + fbx_simple_property(DecayStart, int, 0); + fbx_simple_property(FileName, std::string, ""); + + fbx_simple_property(EnableNearAttenuation, bool, false); + fbx_simple_property(NearAttenuationStart, float, 0.0f); + fbx_simple_property(NearAttenuationEnd, float, 0.0f); + fbx_simple_property(EnableFarAttenuation, bool, false); + fbx_simple_property(FarAttenuationStart, float, 0.0f); + fbx_simple_property(FarAttenuationEnd, float, 0.0f); + + fbx_simple_property(CastShadows, bool, true); + fbx_simple_property(ShadowColor, aiVector3D, aiVector3D(0,0,0)); + + fbx_simple_property(AreaLightShape, int, 0); + + fbx_simple_property(LeftBarnDoor, float, 20.0f); + fbx_simple_property(RightBarnDoor, float, 20.0f); + fbx_simple_property(TopBarnDoor, float, 20.0f); + fbx_simple_property(BottomBarnDoor, float, 20.0f); + fbx_simple_property(EnableBarnDoor, bool, true); + + +private: +}; + + +/** DOM base class for FBX models (even though its semantics are more "node" than "model" */ +class Model : public Object +{ +public: + + Model(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Model(); + +public: + + enum RotOrder + { + RotOrder_EulerXYZ = 0, + RotOrder_EulerXZY, + RotOrder_EulerYZX, + RotOrder_EulerYXZ, + RotOrder_EulerZXY, + RotOrder_EulerZYX, + + RotOrder_SphericXYZ, + + RotOrder_MAX // end-of-enum sentinel + }; + + + enum TransformInheritance + { + TransformInheritance_RrSs = 0, + TransformInheritance_RSrs, + TransformInheritance_Rrs, + + TransformInheritance_MAX // end-of-enum sentinel + }; + +public: + + fbx_simple_property(QuaternionInterpolate, int, 0); + + fbx_simple_property(RotationOffset, aiVector3D, aiVector3D()); + fbx_simple_property(RotationPivot, aiVector3D, aiVector3D()); + fbx_simple_property(ScalingOffset, aiVector3D, aiVector3D()); + fbx_simple_property(ScalingPivot, aiVector3D, aiVector3D()); + fbx_simple_property(TranslationActive, bool, false); + + fbx_simple_property(TranslationMin, aiVector3D, aiVector3D()); + fbx_simple_property(TranslationMax, aiVector3D, aiVector3D()); + + fbx_simple_property(TranslationMinX, bool, false); + fbx_simple_property(TranslationMaxX, bool, false); + fbx_simple_property(TranslationMinY, bool, false); + fbx_simple_property(TranslationMaxY, bool, false); + fbx_simple_property(TranslationMinZ, bool, false); + fbx_simple_property(TranslationMaxZ, bool, false); + + fbx_simple_enum_property(RotationOrder, RotOrder, 0); + fbx_simple_property(RotationSpaceForLimitOnly, bool, false); + fbx_simple_property(RotationStiffnessX, float, 0.0f); + fbx_simple_property(RotationStiffnessY, float, 0.0f); + fbx_simple_property(RotationStiffnessZ, float, 0.0f); + fbx_simple_property(AxisLen, float, 0.0f); + + fbx_simple_property(PreRotation, aiVector3D, aiVector3D()); + fbx_simple_property(PostRotation, aiVector3D, aiVector3D()); + fbx_simple_property(RotationActive, bool, false); + + fbx_simple_property(RotationMin, aiVector3D, aiVector3D()); + fbx_simple_property(RotationMax, aiVector3D, aiVector3D()); + + fbx_simple_property(RotationMinX, bool, false); + fbx_simple_property(RotationMaxX, bool, false); + fbx_simple_property(RotationMinY, bool, false); + fbx_simple_property(RotationMaxY, bool, false); + fbx_simple_property(RotationMinZ, bool, false); + fbx_simple_property(RotationMaxZ, bool, false); + fbx_simple_enum_property(InheritType, TransformInheritance, 0); + + fbx_simple_property(ScalingActive, bool, false); + fbx_simple_property(ScalingMin, aiVector3D, aiVector3D()); + fbx_simple_property(ScalingMax, aiVector3D, aiVector3D(1.f,1.f,1.f)); + fbx_simple_property(ScalingMinX, bool, false); + fbx_simple_property(ScalingMaxX, bool, false); + fbx_simple_property(ScalingMinY, bool, false); + fbx_simple_property(ScalingMaxY, bool, false); + fbx_simple_property(ScalingMinZ, bool, false); + fbx_simple_property(ScalingMaxZ, bool, false); + + fbx_simple_property(GeometricTranslation, aiVector3D, aiVector3D()); + fbx_simple_property(GeometricRotation, aiVector3D, aiVector3D()); + fbx_simple_property(GeometricScaling, aiVector3D, aiVector3D(1.f, 1.f, 1.f)); + + fbx_simple_property(MinDampRangeX, float, 0.0f); + fbx_simple_property(MinDampRangeY, float, 0.0f); + fbx_simple_property(MinDampRangeZ, float, 0.0f); + fbx_simple_property(MaxDampRangeX, float, 0.0f); + fbx_simple_property(MaxDampRangeY, float, 0.0f); + fbx_simple_property(MaxDampRangeZ, float, 0.0f); + + fbx_simple_property(MinDampStrengthX, float, 0.0f); + fbx_simple_property(MinDampStrengthY, float, 0.0f); + fbx_simple_property(MinDampStrengthZ, float, 0.0f); + fbx_simple_property(MaxDampStrengthX, float, 0.0f); + fbx_simple_property(MaxDampStrengthY, float, 0.0f); + fbx_simple_property(MaxDampStrengthZ, float, 0.0f); + + fbx_simple_property(PreferredAngleX, float, 0.0f); + fbx_simple_property(PreferredAngleY, float, 0.0f); + fbx_simple_property(PreferredAngleZ, float, 0.0f); + + fbx_simple_property(Show, bool, true); + fbx_simple_property(LODBox, bool, false); + fbx_simple_property(Freeze, bool, false); + +public: + + const std::string& Shading() const { + return shading; + } + + const std::string& Culling() const { + return culling; + } + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + + /** Get material links */ + const std::vector<const Material*>& GetMaterials() const { + return materials; + } + + + /** Get geometry links */ + const std::vector<const Geometry*>& GetGeometry() const { + return geometry; + } + + + /** Get node attachments */ + const std::vector<const NodeAttribute*>& GetAttributes() const { + return attributes; + } + +public: + + /** convenience method to check if the node has a Null node marker */ + bool IsNull() const; + + +private: + + void ResolveLinks(const Element& element, const Document& doc); + +private: + + std::vector<const Material*> materials; + std::vector<const Geometry*> geometry; + std::vector<const NodeAttribute*> attributes; + + std::string shading; + std::string culling; + boost::shared_ptr<const PropertyTable> props; +}; + +/** DOM class for generic FBX textures */ +class Texture : public Object +{ +public: + + Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Texture(); + +public: + + const std::string& Type() const { + return type; + } + + const std::string& FileName() const { + return fileName; + } + + const std::string& RelativeFilename() const { + return relativeFileName; + } + + const std::string& AlphaSource() const { + return alphaSource; + } + + const aiVector2D& UVTranslation() const { + return uvTrans; + } + + const aiVector2D& UVScaling() const { + return uvScaling; + } + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + + // return a 4-tuple + const unsigned int* Crop() const { + return crop; + } + +private: + + aiVector2D uvTrans; + aiVector2D uvScaling; + + std::string type; + std::string relativeFileName; + std::string fileName; + std::string alphaSource; + boost::shared_ptr<const PropertyTable> props; + + unsigned int crop[4]; +}; + +/** DOM class for layered FBX textures */ +class LayeredTexture : public Object +{ +public: + + LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~LayeredTexture(); + + //Can only be called after construction of the layered texture object due to construction flag. + void fillTexture(const Document& doc); + + enum BlendMode + { + BlendMode_Translucent, + BlendMode_Additive, + BlendMode_Modulate, + BlendMode_Modulate2, + BlendMode_Over, + BlendMode_Normal, + BlendMode_Dissolve, + BlendMode_Darken, + BlendMode_ColorBurn, + BlendMode_LinearBurn, + BlendMode_DarkerColor, + BlendMode_Lighten, + BlendMode_Screen, + BlendMode_ColorDodge, + BlendMode_LinearDodge, + BlendMode_LighterColor, + BlendMode_SoftLight, + BlendMode_HardLight, + BlendMode_VividLight, + BlendMode_LinearLight, + BlendMode_PinLight, + BlendMode_HardMix, + BlendMode_Difference, + BlendMode_Exclusion, + BlendMode_Subtract, + BlendMode_Divide, + BlendMode_Hue, + BlendMode_Saturation, + BlendMode_Color, + BlendMode_Luminosity, + BlendMode_Overlay, + BlendMode_BlendModeCount + }; + + const Texture* getTexture() const + { + return texture; + } + BlendMode GetBlendMode() + { + return blendMode; + } + float Alpha() + { + return alpha; + } +private: + const Texture* texture; + BlendMode blendMode; + float alpha; +}; + +typedef std::fbx_unordered_map<std::string, const Texture*> TextureMap; +typedef std::fbx_unordered_map<std::string, const LayeredTexture*> LayeredTextureMap; + + +/** DOM class for generic FBX materials */ +class Material : public Object +{ +public: + + Material(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Material(); + +public: + + const std::string& GetShadingModel() const { + return shading; + } + + bool IsMultilayer() const { + return multilayer; + } + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + + const TextureMap& Textures() const { + return textures; + } + + const LayeredTextureMap& LayeredTextures() const { + return layeredTextures; + } + +private: + + std::string shading; + bool multilayer; + boost::shared_ptr<const PropertyTable> props; + + TextureMap textures; + LayeredTextureMap layeredTextures; +}; + + +/** DOM base class for all kinds of FBX geometry */ +class Geometry : public Object +{ +public: + + Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc); + ~Geometry(); + +public: + + /** Get the Skin attached to this geometry or NULL */ + const Skin* const DeformerSkin() const { + return skin; + } + +private: + + const Skin* skin; +}; + + +typedef std::vector<int> MatIndexArray; + + +/** DOM class for FBX geometry of type "Mesh"*/ +class MeshGeometry : public Geometry +{ + +public: + + MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc); + ~MeshGeometry(); + +public: + + /** Get a list of all vertex points, non-unique*/ + const std::vector<aiVector3D>& GetVertices() const { + return vertices; + } + + /** Get a list of all vertex normals or an empty array if + * no normals are specified. */ + const std::vector<aiVector3D>& GetNormals() const { + return normals; + } + + /** Get a list of all vertex tangents or an empty array + * if no tangents are specified */ + const std::vector<aiVector3D>& GetTangents() const { + return tangents; + } + + /** Get a list of all vertex binormals or an empty array + * if no binormals are specified */ + const std::vector<aiVector3D>& GetBinormals() const { + return binormals; + } + + /** Return list of faces - each entry denotes a face and specifies + * how many vertices it has. Vertices are taken from the + * vertex data arrays in sequential order. */ + const std::vector<unsigned int>& GetFaceIndexCounts() const { + return faces; + } + + /** Get a UV coordinate slot, returns an empty array if + * the requested slot does not exist. */ + const std::vector<aiVector2D>& GetTextureCoords(unsigned int index) const { + static const std::vector<aiVector2D> empty; + return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index]; + } + + + /** Get a UV coordinate slot, returns an empty array if + * the requested slot does not exist. */ + std::string GetTextureCoordChannelName(unsigned int index) const { + return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : uvNames[index]; + } + + /** Get a vertex color coordinate slot, returns an empty array if + * the requested slot does not exist. */ + const std::vector<aiColor4D>& GetVertexColors(unsigned int index) const { + static const std::vector<aiColor4D> empty; + return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : colors[index]; + } + + + /** Get per-face-vertex material assignments */ + const MatIndexArray& GetMaterialIndices() const { + return materials; + } + + + /** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL + * if the vertex index is not valid. */ + const unsigned int* ToOutputVertexIndex(unsigned int in_index, unsigned int& count) const { + if(in_index >= mapping_counts.size()) { + return NULL; + } + + ai_assert(mapping_counts.size() == mapping_offsets.size()); + count = mapping_counts[in_index]; + + ai_assert(count != 0); + ai_assert(mapping_offsets[in_index] + count <= mappings.size()); + + return &mappings[mapping_offsets[in_index]]; + } + + + /** Determine the face to which a particular output vertex index belongs. + * This mapping is always unique. */ + unsigned int FaceForVertexIndex(unsigned int in_index) const { + ai_assert(in_index < vertices.size()); + + // in the current conversion pattern this will only be needed if + // weights are present, so no need to always pre-compute this table + if (facesVertexStartIndices.empty()) { + facesVertexStartIndices.resize(faces.size() + 1, 0); + + std::partial_sum(faces.begin(), faces.end(), facesVertexStartIndices.begin() + 1); + facesVertexStartIndices.pop_back(); + } + + ai_assert(facesVertexStartIndices.size() == faces.size()); + const std::vector<unsigned int>::iterator it = std::upper_bound( + facesVertexStartIndices.begin(), + facesVertexStartIndices.end(), + in_index + ); + + return static_cast<unsigned int>(std::distance(facesVertexStartIndices.begin(), it - 1)); + } + +public: + +private: + + void ReadLayer(const Scope& layer); + void ReadLayerElement(const Scope& layerElement); + void ReadVertexData(const std::string& type, int index, const Scope& source); + + void ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + + void ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + + void ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + + void ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + + void ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + + void ReadVertexDataMaterials(MatIndexArray& materials_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType); + +private: + + // cached data arrays + MatIndexArray materials; + std::vector<aiVector3D> vertices; + std::vector<unsigned int> faces; + mutable std::vector<unsigned int> facesVertexStartIndices; + std::vector<aiVector3D> tangents; + std::vector<aiVector3D> binormals; + std::vector<aiVector3D> normals; + + std::string uvNames[AI_MAX_NUMBER_OF_TEXTURECOORDS]; + std::vector<aiVector2D> uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS]; + std::vector<aiColor4D> colors[AI_MAX_NUMBER_OF_COLOR_SETS]; + + std::vector<unsigned int> mapping_counts; + std::vector<unsigned int> mapping_offsets; + std::vector<unsigned int> mappings; +}; + +typedef std::vector<uint64_t> KeyTimeList; +typedef std::vector<float> KeyValueList; + +/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */ +class AnimationCurve : public Object +{ +public: + + AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc); + ~AnimationCurve(); + +public: + + /** get list of keyframe positions (time). + * Invariant: |GetKeys()| > 0 */ + const KeyTimeList& GetKeys() const { + return keys; + } + + + /** get list of keyframe values. + * Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/ + const KeyValueList& GetValues() const { + return values; + } + + + const std::vector<float>& GetAttributes() const { + return attributes; + } + + const std::vector<unsigned int>& GetFlags() const { + return flags; + } + +private: + + KeyTimeList keys; + KeyValueList values; + std::vector<float> attributes; + std::vector<unsigned int> flags; +}; + +// property-name -> animation curve +typedef std::map<std::string, const AnimationCurve*> AnimationCurveMap; + + +/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */ +class AnimationCurveNode : public Object +{ +public: + + /* the optional whitelist specifies a list of property names for which the caller + wants animations for. If the curve node does not match one of these, std::range_error + will be thrown. */ + AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc, + const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0); + + ~AnimationCurveNode(); + +public: + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + + + const AnimationCurveMap& Curves() const; + + /** Object the curve is assigned to, this can be NULL if the + * target object has no DOM representation or could not + * be read for other reasons.*/ + const Object* Target() const { + return target; + } + + const Model* TargetAsModel() const { + return dynamic_cast<const Model*>(target); + } + + const NodeAttribute* TargetAsNodeAttribute() const { + return dynamic_cast<const NodeAttribute*>(target); + } + + /** Property of Target() that is being animated*/ + const std::string& TargetProperty() const { + return prop; + } + +private: + + const Object* target; + boost::shared_ptr<const PropertyTable> props; + mutable AnimationCurveMap curves; + + std::string prop; + const Document& doc; +}; + +typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList; + + +/** Represents a FBX animation layer (i.e. a list of node animations) */ +class AnimationLayer : public Object +{ +public: + + + AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc); + ~AnimationLayer(); + +public: + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + + /* the optional whitelist specifies a list of property names for which the caller + wants animations for. Curves not matching this list will not be added to the + animation layer. */ + AnimationCurveNodeList Nodes(const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0) const; + +private: + + boost::shared_ptr<const PropertyTable> props; + const Document& doc; +}; + + +typedef std::vector<const AnimationLayer*> AnimationLayerList; + + +/** Represents a FBX animation stack (i.e. a list of animation layers) */ +class AnimationStack : public Object +{ +public: + + AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc); + ~AnimationStack(); + +public: + + fbx_simple_property(LocalStart, uint64_t, 0L); + fbx_simple_property(LocalStop, uint64_t, 0L); + fbx_simple_property(ReferenceStart, uint64_t, 0L); + fbx_simple_property(ReferenceStop, uint64_t, 0L); + + + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + + + const AnimationLayerList& Layers() const { + return layers; + } + +private: + + boost::shared_ptr<const PropertyTable> props; + AnimationLayerList layers; +}; + + +/** DOM class for deformers */ +class Deformer : public Object +{ +public: + + Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Deformer(); + +public: + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + +private: + + boost::shared_ptr<const PropertyTable> props; +}; + +typedef std::vector<float> WeightArray; +typedef std::vector<unsigned int> WeightIndexArray; + + +/** DOM class for skin deformer clusters (aka subdeformers) */ +class Cluster : public Deformer +{ +public: + + Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Cluster(); + +public: + + /** get the list of deformer weights associated with this cluster. + * Use #GetIndices() to get the associated vertices. Both arrays + * have the same size (and may also be empty). */ + const WeightArray& GetWeights() const { + return weights; + } + + /** get indices into the vertex data of the geometry associated + * with this cluster. Use #GetWeights() to get the associated weights. + * Both arrays have the same size (and may also be empty). */ + const WeightIndexArray& GetIndices() const { + return indices; + } + + /** */ + const aiMatrix4x4& Transform() const { + return transform; + } + + const aiMatrix4x4& TransformLink() const { + return transformLink; + } + + const Model* const TargetNode() const { + return node; + } + +private: + + WeightArray weights; + WeightIndexArray indices; + + aiMatrix4x4 transform; + aiMatrix4x4 transformLink; + + const Model* node; +}; + + + +/** DOM class for skin deformers */ +class Skin : public Deformer +{ +public: + + Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name); + ~Skin(); + +public: + + float DeformAccuracy() const { + return accuracy; + } + + + const std::vector<const Cluster*>& Clusters() const { + return clusters; + } + +private: + + float accuracy; + std::vector<const Cluster*> clusters; +}; + + + +/** Represents a link between two FBX objects. */ +class Connection +{ +public: + + Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, const Document& doc); + ~Connection(); + + // note: a connection ensures that the source and dest objects exist, but + // not that they have DOM representations, so the return value of one of + // these functions can still be NULL. + const Object* SourceObject() const; + const Object* DestinationObject() const; + + // these, however, are always guaranteed to be valid + LazyObject& LazySourceObject() const; + LazyObject& LazyDestinationObject() const; + + + /** return the name of the property the connection is attached to. + * this is an empty string for object to object (OO) connections. */ + const std::string& PropertyName() const { + return prop; + } + + uint64_t InsertionOrder() const { + return insertionOrder; + } + + int CompareTo(const Connection* c) const { + // note: can't subtract because this would overflow uint64_t + if(InsertionOrder() > c->InsertionOrder()) { + return 1; + } + else if(InsertionOrder() < c->InsertionOrder()) { + return -1; + } + return 0; + } + + bool Compare(const Connection* c) const { + return InsertionOrder() < c->InsertionOrder(); + } + +public: + + uint64_t insertionOrder; + const std::string prop; + + uint64_t src, dest; + const Document& doc; +}; + + + // XXX again, unique_ptr would be useful. shared_ptr is too + // bloated since the objects have a well-defined single owner + // during their entire lifetime (Document). FBX files have + // up to many thousands of objects (most of which we never use), + // so the memory overhead for them should be kept at a minimum. + typedef std::map<uint64_t, LazyObject*> ObjectMap; + typedef std::fbx_unordered_map<std::string, boost::shared_ptr<const PropertyTable> > PropertyTemplateMap; + + + typedef std::multimap<uint64_t, const Connection*> ConnectionMap; + + +/** DOM class for global document settings, a single instance per document can + * be accessed via Document.Globals(). */ +class FileGlobalSettings +{ +public: + + FileGlobalSettings(const Document& doc, boost::shared_ptr<const PropertyTable> props); + ~FileGlobalSettings(); + +public: + + const PropertyTable& Props() const { + ai_assert(props.get()); + return *props.get(); + } + + const Document& GetDocument() const { + return doc; + } + + + fbx_simple_property(UpAxis, int, 1); + fbx_simple_property(UpAxisSign, int, 1); + fbx_simple_property(FrontAxis, int, 2); + fbx_simple_property(FrontAxisSign, int, 1); + fbx_simple_property(CoordAxis, int, 0); + fbx_simple_property(CoordAxisSign, int, 1); + fbx_simple_property(OriginalUpAxis, int, 0); + fbx_simple_property(OriginalUpAxisSign, int, 1); + fbx_simple_property(UnitScaleFactor, double, 1); + fbx_simple_property(OriginalUnitScaleFactor, double, 1); + fbx_simple_property(AmbientColor, aiVector3D, aiVector3D(0,0,0)); + fbx_simple_property(DefaultCamera, std::string, ""); + + + enum FrameRate { + FrameRate_DEFAULT = 0, + FrameRate_120 = 1, + FrameRate_100 = 2, + FrameRate_60 = 3, + FrameRate_50 = 4, + FrameRate_48 = 5, + FrameRate_30 = 6, + FrameRate_30_DROP = 7, + FrameRate_NTSC_DROP_FRAME = 8, + FrameRate_NTSC_FULL_FRAME = 9, + FrameRate_PAL = 10, + FrameRate_CINEMA = 11, + FrameRate_1000 = 12, + FrameRate_CINEMA_ND = 13, + FrameRate_CUSTOM = 14, + + FrameRate_MAX// end-of-enum sentinel + }; + + fbx_simple_enum_property(TimeMode, FrameRate, FrameRate_DEFAULT); + fbx_simple_property(TimeSpanStart, uint64_t, 0L); + fbx_simple_property(TimeSpanStop, uint64_t, 0L); + fbx_simple_property(CustomFrameRate, float, -1.0f); + + +private: + + boost::shared_ptr<const PropertyTable> props; + const Document& doc; +}; + + + + +/** DOM root for a FBX file */ +class Document +{ +public: + + Document(const Parser& parser, const ImportSettings& settings); + ~Document(); + +public: + + LazyObject* GetObject(uint64_t id) const; + + bool IsBinary() const { + return parser.IsBinary(); + } + + unsigned int FBXVersion() const { + return fbxVersion; + } + + const std::string& Creator() const { + return creator; + } + + // elements (in this order): Uear, Month, Day, Hour, Second, Millisecond + const unsigned int* CreationTimeStamp() const { + return creationTimeStamp; + } + + const FileGlobalSettings& GlobalSettings() const { + ai_assert(globals.get()); + return *globals.get(); + } + + const PropertyTemplateMap& Templates() const { + return templates; + } + + const ObjectMap& Objects() const { + return objects; + } + + const ImportSettings& Settings() const { + return settings; + } + + const ConnectionMap& ConnectionsBySource() const { + return src_connections; + } + + const ConnectionMap& ConnectionsByDestination() const { + return dest_connections; + } + + // note: the implicit rule in all DOM classes is to always resolve + // from destination to source (since the FBX object hierarchy is, + // with very few exceptions, a DAG, this avoids cycles). In all + // cases that may involve back-facing edges in the object graph, + // use LazyObject::IsBeingConstructed() to check. + + std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source) const; + std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest) const; + + std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source, const char* classname) const; + std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest, const char* classname) const; + + std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source, + const char* const* classnames, size_t count) const; + std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest, + const char* const* classnames, + size_t count) const; + + const std::vector<const AnimationStack*>& AnimationStacks() const; + +private: + + std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, const ConnectionMap&) const; + std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, bool is_src, + const ConnectionMap&, + const char* const* classnames, + size_t count) const; + +private: + + void ReadHeader(); + void ReadObjects(); + void ReadPropertyTemplates(); + void ReadConnections(); + void ReadGlobalSettings(); + +private: + + const ImportSettings& settings; + + ObjectMap objects; + const Parser& parser; + + PropertyTemplateMap templates; + ConnectionMap src_connections; + ConnectionMap dest_connections; + + unsigned int fbxVersion; + std::string creator; + unsigned int creationTimeStamp[7]; + + std::vector<uint64_t> animationStacks; + mutable std::vector<const AnimationStack*> animationStacksResolved; + + boost::scoped_ptr<FileGlobalSettings> globals; +}; + +} +} + +#endif diff --git a/src/3rdparty/assimp/code/FBXDocumentUtil.cpp b/src/3rdparty/assimp/code/FBXDocumentUtil.cpp new file mode 100644 index 000000000..5efbcb2b7 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXDocumentUtil.cpp @@ -0,0 +1,133 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXDocumentUtil.cpp + * @brief Implementation of the FBX DOM utility functions declared in FBXDocumentUtil.h + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXUtil.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { +namespace Util { + +// ------------------------------------------------------------------------------------------------ +// signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError. +void DOMError(const std::string& message, const Token& token) +{ + throw DeadlyImportError(Util::AddTokenText("FBX-DOM",message,&token)); +} + +// ------------------------------------------------------------------------------------------------ +void DOMError(const std::string& message, const Element* element /*= NULL*/) +{ + if(element) { + DOMError(message,element->KeyToken()); + } + throw DeadlyImportError("FBX-DOM " + message); +} + + +// ------------------------------------------------------------------------------------------------ +// print warning, do return +void DOMWarning(const std::string& message, const Token& token) +{ + if(DefaultLogger::get()) { + DefaultLogger::get()->warn(Util::AddTokenText("FBX-DOM",message,&token)); + } +} + +// ------------------------------------------------------------------------------------------------ +void DOMWarning(const std::string& message, const Element* element /*= NULL*/) +{ + if(element) { + DOMWarning(message,element->KeyToken()); + return; + } + if(DefaultLogger::get()) { + DefaultLogger::get()->warn("FBX-DOM: " + message); + } +} + + +// ------------------------------------------------------------------------------------------------ +// fetch a property table and the corresponding property template +boost::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc, + const std::string& templateName, + const Element &element, + const Scope& sc, + bool no_warn /*= false*/) +{ + const Element* const Properties70 = sc["Properties70"]; + boost::shared_ptr<const PropertyTable> templateProps = boost::shared_ptr<const PropertyTable>( + static_cast<const PropertyTable*>(NULL)); + + if(templateName.length()) { + PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName); + if(it != doc.Templates().end()) { + templateProps = (*it).second; + } + } + + if(!Properties70) { + if(!no_warn) { + DOMWarning("property table (Properties70) not found",&element); + } + if(templateProps) { + return templateProps; + } + else { + return boost::make_shared<const PropertyTable>(); + } + } + return boost::make_shared<const PropertyTable>(*Properties70,templateProps); +} +} // !Util +} // !FBX +} // !Assimp + +#endif diff --git a/src/3rdparty/assimp/code/FBXDocumentUtil.h b/src/3rdparty/assimp/code/FBXDocumentUtil.h new file mode 100644 index 000000000..6f150b6d5 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXDocumentUtil.h @@ -0,0 +1,114 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXDocumentUtil.h + * @brief FBX internal utilities used by the DOM reading code + */ +#ifndef INCLUDED_AI_FBX_DOCUMENT_UTIL_H +#define INCLUDED_AI_FBX_DOCUMENT_UTIL_H + +namespace Assimp { +namespace FBX { +namespace Util { + + +/* DOM/Parse error reporting - does not return */ +AI_WONT_RETURN void DOMError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX; +AI_WONT_RETURN void DOMError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX; + +// does return +void DOMWarning(const std::string& message, const Token& token); +void DOMWarning(const std::string& message, const Element* element = NULL); + + +// fetch a property table and the corresponding property template +boost::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc, + const std::string& templateName, + const Element &element, + const Scope& sc, + bool no_warn = false); + + +// ------------------------------------------------------------------------------------------------ +template <typename T> +inline const T* ProcessSimpleConnection(const Connection& con, + bool is_object_property_conn, + const char* name, + const Element& element, + const char** propNameOut = NULL) +{ + if (is_object_property_conn && !con.PropertyName().length()) { + DOMWarning("expected incoming " + std::string(name) + + " link to be an object-object connection, ignoring", + &element + ); + return NULL; + } + else if (!is_object_property_conn && con.PropertyName().length()) { + DOMWarning("expected incoming " + std::string(name) + + " link to be an object-property connection, ignoring", + &element + ); + return NULL; + } + + if(is_object_property_conn && propNameOut) { + // note: this is ok, the return value of PropertyValue() is guaranteed to + // remain valid and unchanged as long as the document exists. + *propNameOut = con.PropertyName().c_str(); + } + + const Object* const ob = con.SourceObject(); + if(!ob) { + DOMWarning("failed to read source object for incoming" + std::string(name) + + " link, ignoring", + &element); + return NULL; + } + + return dynamic_cast<const T*>(ob); +} + + +} //!Util +} //!FBX +} //!Assimp + +#endif diff --git a/src/3rdparty/assimp/code/FBXImportSettings.h b/src/3rdparty/assimp/code/FBXImportSettings.h new file mode 100644 index 000000000..47fc1d6a6 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXImportSettings.h @@ -0,0 +1,142 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXImportSettings.h + * @brief FBX importer runtime configuration + */ +#ifndef INCLUDED_AI_FBX_IMPORTSETTINGS_H +#define INCLUDED_AI_FBX_IMPORTSETTINGS_H + +namespace Assimp { +namespace FBX { + +/** FBX import settings, parts of which are publicly accessible via their corresponding AI_CONFIG constants */ +struct ImportSettings +{ + ImportSettings() + : strictMode(true) + , readAllLayers(true) + , readAllMaterials() + , readMaterials(true) + , readCameras(true) + , readLights(true) + , readAnimations(true) + , readWeights(true) + , preservePivots(true) + , optimizeEmptyAnimationCurves(true) + {} + + + /** enable strict mode: + * - only accept fbx 2012, 2013 files + * - on the slightest error, give up. + * + * Basically, strict mode means that the fbx file will actually + * be validated. Strict mode is off by default. */ + bool strictMode; + + /** specifies whether all geometry layers are read and scanned for + * usable data channels. The FBX spec indicates that many readers + * will only read the first channel and that this is in some way + * the recommended way- in reality, however, it happens a lot that + * vertex data is spread among multiple layers. The default + * value for this option is true.*/ + bool readAllLayers; + + /** specifies whether all materials are read, or only those that + * are referenced by at least one mesh. Reading all materials + * may make FBX reading a lot slower since all objects + * need to be processed . + * This bit is ignored unless readMaterials=true*/ + bool readAllMaterials; + + + /** import materials (true) or skip them and assign a default + * material. The default value is true.*/ + bool readMaterials; + + /** import cameras? Default value is true.*/ + bool readCameras; + + /** import light sources? Default value is true.*/ + bool readLights; + + /** import animations (i.e. animation curves, the node + * skeleton is always imported). Default value is true. */ + bool readAnimations; + + /** read bones (vertex weights and deform info). + * Default value is true. */ + bool readWeights; + + /** preserve transformation pivots and offsets. Since these can + * not directly be represented in assimp, additional dummy + * nodes will be generated. Note that settings this to false + * can make animation import a lot slower. The default value + * is true. + * + * The naming scheme for the generated nodes is: + * <OriginalName>_$AssimpFbx$_<TransformName> + * + * where <TransformName> is one of + * RotationPivot + * RotationOffset + * PreRotation + * PostRotation + * ScalingPivot + * ScalingOffset + * Translation + * Scaling + * Rotation + **/ + bool preservePivots; + + /** do not import animation curves that specify a constant + * values matching the corresponding node transformation. + * The default value is true. */ + bool optimizeEmptyAnimationCurves; +}; + + +} // !FBX +} // !Assimp + +#endif + diff --git a/src/3rdparty/assimp/code/FBXImporter.cpp b/src/3rdparty/assimp/code/FBXImporter.cpp new file mode 100644 index 000000000..56e99063b --- /dev/null +++ b/src/3rdparty/assimp/code/FBXImporter.cpp @@ -0,0 +1,189 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXImporter.cpp + * @brief Implementation of the FBX importer. + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include <exception> +#include <iterator> +#include <boost/tuple/tuple.hpp> + +#include "FBXImporter.h" + +#include "FBXTokenizer.h" +#include "FBXParser.h" +#include "FBXUtil.h" +#include "FBXDocument.h" +#include "FBXConverter.h" + +#include "StreamReader.h" +#include "MemoryIOWrapper.h" + +namespace Assimp { + template<> const std::string LogFunctions<FBXImporter>::log_prefix = "FBX: "; +} + +using namespace Assimp; +using namespace Assimp::Formatter; +using namespace Assimp::FBX; + +namespace { +static const aiImporterDesc desc = { + "Autodesk FBX Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "fbx" +}; +} + +// ------------------------------------------------------------------------------------------------ +// Constructor to be privately used by #Importer +FBXImporter::FBXImporter() +{} + +// ------------------------------------------------------------------------------------------------ +// Destructor, private as well +FBXImporter::~FBXImporter() +{ +} + +// ------------------------------------------------------------------------------------------------ +// Returns whether the class can handle the format of the given file. +bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const +{ + const std::string& extension = GetExtension(pFile); + if (extension == "fbx") { + return true; + } + + else if ((!extension.length() || checkSig) && pIOHandler) { + // at least ascii FBX files usually have a 'FBX' somewhere in their head + const char* tokens[] = {"FBX"}; + return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); + } + return false; +} + +// ------------------------------------------------------------------------------------------------ +// List all extensions handled by this loader +const aiImporterDesc* FBXImporter::GetInfo () const +{ + return &desc; +} + + +// ------------------------------------------------------------------------------------------------ +// Setup configuration properties for the loader +void FBXImporter::SetupProperties(const Importer* pImp) +{ + settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true); + settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false); + settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true); + settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true); + settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true); + settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true); + settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false); + settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true); + settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true); +} + + +// ------------------------------------------------------------------------------------------------ +// Imports the given file into the given scene structure. +void FBXImporter::InternReadFile( const std::string& pFile, + aiScene* pScene, IOSystem* pIOHandler) +{ + boost::scoped_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb")); + if (!stream) { + ThrowException("Could not open file for reading"); + } + + // read entire file into memory - no streaming for this, fbx + // files can grow large, but the assimp output data structure + // then becomes very large, too. Assimp doesn't support + // streaming for its output data structures so the net win with + // streaming input data would be very low. + std::vector<char> contents; + contents.resize(stream->FileSize()); + + stream->Read(&*contents.begin(),contents.size(),1); + const char* const begin = &*contents.begin(); + + // broadphase tokenizing pass in which we identify the core + // syntax elements of FBX (brackets, commas, key:value mappings) + TokenList tokens; + try { + + bool is_binary = false; + if (!strncmp(begin,"Kaydara FBX Binary",18)) { + is_binary = true; + TokenizeBinary(tokens,begin,contents.size()); + } + else { + Tokenize(tokens,begin); + } + + // use this information to construct a very rudimentary + // parse-tree representing the FBX scope structure + Parser parser(tokens, is_binary); + + // take the raw parse-tree and convert it to a FBX DOM + Document doc(parser,settings); + + // convert the FBX DOM to aiScene + ConvertToAssimpScene(pScene,doc); + } + catch(std::exception&) { + std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>()); + throw; + } +} + +#endif // !ASSIMP_BUILD_NO_FBX_IMPORTER diff --git a/src/3rdparty/assimp/code/FBXImporter.h b/src/3rdparty/assimp/code/FBXImporter.h new file mode 100644 index 000000000..635411397 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXImporter.h @@ -0,0 +1,107 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXImporter.h + * @brief Declaration of the FBX main importer class + */ +#ifndef INCLUDED_AI_FBX_IMPORTER_H +#define INCLUDED_AI_FBX_IMPORTER_H + +#include "BaseImporter.h" +#include "LogAux.h" + +#include "FBXImportSettings.h" + +namespace Assimp { + + // TinyFormatter.h + namespace Formatter { + template <typename T,typename TR, typename A> class basic_formatter; + typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; + } + + +// ------------------------------------------------------------------------------------------- +/** Load the Autodesk FBX file format. + + See http://en.wikipedia.org/wiki/FBX +*/ +// ------------------------------------------------------------------------------------------- +class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> +{ +public: + FBXImporter(); + ~FBXImporter(); + + +public: + + // -------------------- + bool CanRead( const std::string& pFile, + IOSystem* pIOHandler, + bool checkSig + ) const; + +protected: + + // -------------------- + const aiImporterDesc* GetInfo () const; + + // -------------------- + void SetupProperties(const Importer* pImp); + + // -------------------- + void InternReadFile( const std::string& pFile, + aiScene* pScene, + IOSystem* pIOHandler + ); + +private: + + +private: + + FBX::ImportSettings settings; + +}; // !class FBXImporter + +} // end of namespace Assimp +#endif // !INCLUDED_AI_FBX_IMPORTER_H + diff --git a/src/3rdparty/assimp/code/FBXMaterial.cpp b/src/3rdparty/assimp/code/FBXMaterial.cpp new file mode 100644 index 000000000..a5e2a1169 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXMaterial.cpp @@ -0,0 +1,259 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXMaterial.cpp + * @brief Assimp::FBX::Material and Assimp::FBX::Texture implementation + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXImporter.h" +#include "FBXImportSettings.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + +// ------------------------------------------------------------------------------------------------ +Material::Material(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: Object(id,element,name) +{ + const Scope& sc = GetRequiredScope(element); + + const Element* const ShadingModel = sc["ShadingModel"]; + const Element* const MultiLayer = sc["MultiLayer"]; + + if(MultiLayer) { + multilayer = !!ParseTokenAsInt(GetRequiredToken(*MultiLayer,0)); + } + + if(ShadingModel) { + shading = ParseTokenAsString(GetRequiredToken(*ShadingModel,0)); + } + else { + DOMWarning("shading mode not specified, assuming phong",&element); + shading = "phong"; + } + + std::string templateName; + + const char* const sh = shading.c_str(); + if(!strcmp(sh,"phong")) { + templateName = "Material.FbxSurfacePhong"; + } + else if(!strcmp(sh,"lambert")) { + templateName = "Material.FbxSurfaceLambert"; + } + else { + DOMWarning("shading mode not recognized: " + shading,&element); + } + + props = GetPropertyTable(doc,templateName,element,sc); + + // resolve texture links + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID()); + BOOST_FOREACH(const Connection* con, conns) { + + // texture link to properties, not objects + if (!con->PropertyName().length()) { + continue; + } + + const Object* const ob = con->SourceObject(); + if(!ob) { + DOMWarning("failed to read source object for texture link, ignoring",&element); + continue; + } + + const Texture* const tex = dynamic_cast<const Texture*>(ob); + if(!tex) { + const LayeredTexture* const layeredTexture = dynamic_cast<const LayeredTexture*>(ob); + if(!layeredTexture) { + DOMWarning("source object for texture link is not a texture or layered texture, ignoring",&element); + continue; + } + const std::string& prop = con->PropertyName(); + if (layeredTextures.find(prop) != layeredTextures.end()) { + DOMWarning("duplicate layered texture link: " + prop,&element); + } + + layeredTextures[prop] = layeredTexture; + ((LayeredTexture*)layeredTexture)->fillTexture(doc); + } + else + { + const std::string& prop = con->PropertyName(); + if (textures.find(prop) != textures.end()) { + DOMWarning("duplicate texture link: " + prop,&element); + } + + textures[prop] = tex; + } + + } +} + + +// ------------------------------------------------------------------------------------------------ +Material::~Material() +{ +} + + +// ------------------------------------------------------------------------------------------------ +Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: Object(id,element,name) +, uvScaling(1.0f,1.0f) +{ + const Scope& sc = GetRequiredScope(element); + + const Element* const Type = sc["Type"]; + const Element* const FileName = sc["FileName"]; + const Element* const RelativeFilename = sc["RelativeFilename"]; + const Element* const ModelUVTranslation = sc["ModelUVTranslation"]; + const Element* const ModelUVScaling = sc["ModelUVScaling"]; + const Element* const Texture_Alpha_Source = sc["Texture_Alpha_Source"]; + const Element* const Cropping = sc["Cropping"]; + + if(Type) { + type = ParseTokenAsString(GetRequiredToken(*Type,0)); + } + + if(FileName) { + fileName = ParseTokenAsString(GetRequiredToken(*FileName,0)); + } + + if(RelativeFilename) { + relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0)); + } + + if(ModelUVTranslation) { + uvTrans = aiVector2D(ParseTokenAsFloat(GetRequiredToken(*ModelUVTranslation,0)), + ParseTokenAsFloat(GetRequiredToken(*ModelUVTranslation,1)) + ); + } + + if(ModelUVScaling) { + uvScaling = aiVector2D(ParseTokenAsFloat(GetRequiredToken(*ModelUVScaling,0)), + ParseTokenAsFloat(GetRequiredToken(*ModelUVScaling,1)) + ); + } + + if(Cropping) { + crop[0] = ParseTokenAsInt(GetRequiredToken(*Cropping,0)); + crop[1] = ParseTokenAsInt(GetRequiredToken(*Cropping,1)); + crop[2] = ParseTokenAsInt(GetRequiredToken(*Cropping,2)); + crop[3] = ParseTokenAsInt(GetRequiredToken(*Cropping,3)); + } + else { + // vc8 doesn't support the crop() syntax in initialization lists + // (and vc9 WARNS about the new (i.e. compliant) behaviour). + crop[0] = crop[1] = crop[2] = crop[3] = 0; + } + + if(Texture_Alpha_Source) { + alphaSource = ParseTokenAsString(GetRequiredToken(*Texture_Alpha_Source,0)); + } + + props = GetPropertyTable(doc,"Texture.FbxFileTexture",element,sc); +} + + +Texture::~Texture() +{ + +} + +LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: Object(id,element,name) +,texture(0) +,blendMode(BlendMode_Modulate) +,alpha(1) +{ + const Scope& sc = GetRequiredScope(element); + + const Element* const BlendModes = sc["BlendModes"]; + const Element* const Alphas = sc["Alphas"]; + + + if(BlendModes!=0) + { + blendMode = (BlendMode)ParseTokenAsInt(GetRequiredToken(*BlendModes,0)); + } + if(Alphas!=0) + { + alpha = ParseTokenAsFloat(GetRequiredToken(*Alphas,0)); + } +} + +LayeredTexture::~LayeredTexture() +{ + +} + +void LayeredTexture::fillTexture(const Document& doc) +{ + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID()); + for(size_t i = 0; i < conns.size();++i) + { + const Connection* con = conns.at(i); + + const Object* const ob = con->SourceObject(); + if(!ob) { + DOMWarning("failed to read source object for texture link, ignoring",&element); + continue; + } + + const Texture* const tex = dynamic_cast<const Texture*>(ob); + + texture = tex; + } +} + +} //!FBX +} //!Assimp + +#endif diff --git a/src/3rdparty/assimp/code/FBXMeshGeometry.cpp b/src/3rdparty/assimp/code/FBXMeshGeometry.cpp new file mode 100644 index 000000000..be3fbd621 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXMeshGeometry.cpp @@ -0,0 +1,540 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXMeshGeometry.cpp + * @brief Assimp::FBX::MeshGeometry implementation + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include <functional> + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXImporter.h" +#include "FBXImportSettings.h" +#include "FBXDocumentUtil.h" + + +namespace Assimp { +namespace FBX { + + using namespace Util; + + +// ------------------------------------------------------------------------------------------------ +Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) + : Object(id, element,name) + , skin() +{ + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer"); + BOOST_FOREACH(const Connection* con, conns) { + const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element); + if(sk) { + skin = sk; + break; + } + } +} + + +// ------------------------------------------------------------------------------------------------ +Geometry::~Geometry() +{ + +} + + + +// ------------------------------------------------------------------------------------------------ +MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) +: Geometry(id, element,name, doc) +{ + const Scope* sc = element.Compound(); + if (!sc) { + DOMError("failed to read Geometry object (class: Mesh), no data scope found"); + } + + // must have Mesh elements: + const Element& Vertices = GetRequiredElement(*sc,"Vertices",&element); + const Element& PolygonVertexIndex = GetRequiredElement(*sc,"PolygonVertexIndex",&element); + + // optional Mesh elements: + const ElementCollection& Layer = sc->GetCollection("Layer"); + + std::vector<aiVector3D> tempVerts; + ParseVectorDataArray(tempVerts,Vertices); + + if(tempVerts.empty()) { + FBXImporter::LogWarn("encountered mesh with no vertices"); + return; + } + + std::vector<int> tempFaces; + ParseVectorDataArray(tempFaces,PolygonVertexIndex); + + if(tempFaces.empty()) { + FBXImporter::LogWarn("encountered mesh with no faces"); + return; + } + + vertices.reserve(tempFaces.size()); + faces.reserve(tempFaces.size() / 3); + + mapping_offsets.resize(tempVerts.size()); + mapping_counts.resize(tempVerts.size(),0); + mappings.resize(tempFaces.size()); + + const size_t vertex_count = tempVerts.size(); + + // generate output vertices, computing an adjacency table to + // preserve the mapping from fbx indices to *this* indexing. + unsigned int count = 0; + BOOST_FOREACH(int index, tempFaces) { + const int absi = index < 0 ? (-index - 1) : index; + if(static_cast<size_t>(absi) >= vertex_count) { + DOMError("polygon vertex index out of range",&PolygonVertexIndex); + } + + vertices.push_back(tempVerts[absi]); + ++count; + + ++mapping_counts[absi]; + + if (index < 0) { + faces.push_back(count); + count = 0; + } + } + + unsigned int cursor = 0; + for (size_t i = 0, e = tempVerts.size(); i < e; ++i) { + mapping_offsets[i] = cursor; + cursor += mapping_counts[i]; + + mapping_counts[i] = 0; + } + + cursor = 0; + BOOST_FOREACH(int index, tempFaces) { + const int absi = index < 0 ? (-index - 1) : index; + mappings[mapping_offsets[absi] + mapping_counts[absi]++] = cursor++; + } + + // if settings.readAllLayers is true: + // * read all layers, try to load as many vertex channels as possible + // if settings.readAllLayers is false: + // * read only the layer with index 0, but warn about any further layers + for (ElementMap::const_iterator it = Layer.first; it != Layer.second; ++it) { + const TokenList& tokens = (*it).second->Tokens(); + + const char* err; + const int index = ParseTokenAsInt(*tokens[0], err); + if(err) { + DOMError(err,&element); + } + + if(doc.Settings().readAllLayers || index == 0) { + const Scope& layer = GetRequiredScope(*(*it).second); + ReadLayer(layer); + } + else { + FBXImporter::LogWarn("ignoring additional geometry layers"); + } + } +} + + +// ------------------------------------------------------------------------------------------------ +MeshGeometry::~MeshGeometry() +{ + +} + + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadLayer(const Scope& layer) +{ + const ElementCollection& LayerElement = layer.GetCollection("LayerElement"); + for (ElementMap::const_iterator eit = LayerElement.first; eit != LayerElement.second; ++eit) { + const Scope& elayer = GetRequiredScope(*(*eit).second); + + ReadLayerElement(elayer); + } +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadLayerElement(const Scope& layerElement) +{ + const Element& Type = GetRequiredElement(layerElement,"Type"); + const Element& TypedIndex = GetRequiredElement(layerElement,"TypedIndex"); + + const std::string& type = ParseTokenAsString(GetRequiredToken(Type,0)); + const int typedIndex = ParseTokenAsInt(GetRequiredToken(TypedIndex,0)); + + const Scope& top = GetRequiredScope(element); + const ElementCollection candidates = top.GetCollection(type); + + for (ElementMap::const_iterator it = candidates.first; it != candidates.second; ++it) { + const int index = ParseTokenAsInt(GetRequiredToken(*(*it).second,0)); + if(index == typedIndex) { + ReadVertexData(type,typedIndex,GetRequiredScope(*(*it).second)); + return; + } + } + + FBXImporter::LogError(Formatter::format("failed to resolve vertex layer element: ") + << type << ", index: " << typedIndex); +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scope& source) +{ + const std::string& MappingInformationType = ParseTokenAsString(GetRequiredToken( + GetRequiredElement(source,"MappingInformationType"),0) + ); + + const std::string& ReferenceInformationType = ParseTokenAsString(GetRequiredToken( + GetRequiredElement(source,"ReferenceInformationType"),0) + ); + + if (type == "LayerElementUV") { + if(index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { + FBXImporter::LogError(Formatter::format("ignoring UV layer, maximum number of UV channels exceeded: ") + << index << " (limit is " << AI_MAX_NUMBER_OF_TEXTURECOORDS << ")" ); + return; + } + + const Element* Name = source["Name"]; + uvNames[index] = ""; + if(Name) { + uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0)); + } + + ReadVertexDataUV(uvs[index],source, + MappingInformationType, + ReferenceInformationType + ); + } + else if (type == "LayerElementMaterial") { + if (materials.size() > 0) { + FBXImporter::LogError("ignoring additional material layer"); + return; + } + + std::vector<int> temp_materials; + + ReadVertexDataMaterials(temp_materials,source, + MappingInformationType, + ReferenceInformationType + ); + + // sometimes, there will be only negative entries. Drop the material + // layer in such a case (I guess it means a default material should + // be used). This is what the converter would do anyway, and it + // avoids loosing the material if there are more material layers + // coming of which at least one contains actual data (did observe + // that with one test file). + const size_t count_neg = std::count_if(temp_materials.begin(),temp_materials.end(),std::bind2nd(std::less<int>(),0)); + if(count_neg == temp_materials.size()) { + FBXImporter::LogWarn("ignoring dummy material layer (all entries -1)"); + return; + } + + std::swap(temp_materials, materials); + } + else if (type == "LayerElementNormal") { + if (normals.size() > 0) { + FBXImporter::LogError("ignoring additional normal layer"); + return; + } + + ReadVertexDataNormals(normals,source, + MappingInformationType, + ReferenceInformationType + ); + } + else if (type == "LayerElementTangent") { + if (tangents.size() > 0) { + FBXImporter::LogError("ignoring additional tangent layer"); + return; + } + + ReadVertexDataTangents(tangents,source, + MappingInformationType, + ReferenceInformationType + ); + } + else if (type == "LayerElementBinormal") { + if (binormals.size() > 0) { + FBXImporter::LogError("ignoring additional binormal layer"); + return; + } + + ReadVertexDataBinormals(binormals,source, + MappingInformationType, + ReferenceInformationType + ); + } + else if (type == "LayerElementColor") { + if(index >= AI_MAX_NUMBER_OF_COLOR_SETS) { + FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ") + << index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")" ); + return; + } + + ReadVertexDataColors(colors[index],source, + MappingInformationType, + ReferenceInformationType + ); + } +} + + +// ------------------------------------------------------------------------------------------------ +// Lengthy utility function to read and resolve a FBX vertex data array - that is, the +// output is in polygon vertex order. This logic is used for reading normals, UVs, colors, +// tangents .. +template <typename T> +void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType, + const char* dataElementName, + const char* indexDataElementName, + size_t vertex_count, + const std::vector<unsigned int>& mapping_counts, + const std::vector<unsigned int>& mapping_offsets, + const std::vector<unsigned int>& mappings) +{ + std::vector<T> tempUV; + ParseVectorDataArray(tempUV,GetRequiredElement(source,dataElementName)); + + // handle permutations of Mapping and Reference type - it would be nice to + // deal with this more elegantly and with less redundancy, but right + // now it seems unavoidable. + if (MappingInformationType == "ByVertice" && ReferenceInformationType == "Direct") { + data_out.resize(vertex_count); + for (size_t i = 0, e = tempUV.size(); i < e; ++i) { + + const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i]; + for (unsigned int j = istart; j < iend; ++j) { + data_out[mappings[j]] = tempUV[i]; + } + } + } + else if (MappingInformationType == "ByVertice" && ReferenceInformationType == "IndexToDirect") { + data_out.resize(vertex_count); + + std::vector<int> uvIndices; + ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); + + for (size_t i = 0, e = uvIndices.size(); i < e; ++i) { + + const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i]; + for (unsigned int j = istart; j < iend; ++j) { + if(static_cast<size_t>(uvIndices[i]) >= tempUV.size()) { + DOMError("index out of range",&GetRequiredElement(source,indexDataElementName)); + } + data_out[mappings[j]] = tempUV[uvIndices[i]]; + } + } + } + else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "Direct") { + if (tempUV.size() != vertex_count) { + FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") + << tempUV.size() << ", expected " << vertex_count + ); + return; + } + + data_out.swap(tempUV); + } + else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "IndexToDirect") { + data_out.resize(vertex_count); + + std::vector<int> uvIndices; + ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName)); + + if (uvIndices.size() != vertex_count) { + FBXImporter::LogError("length of input data unexpected for ByPolygonVertex mapping"); + return; + } + + unsigned int next = 0; + BOOST_FOREACH(int i, uvIndices) { + if(static_cast<size_t>(i) >= tempUV.size()) { + DOMError("index out of range",&GetRequiredElement(source,indexDataElementName)); + } + + data_out[next++] = tempUV[i]; + } + } + else { + FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ") + << MappingInformationType << "," << ReferenceInformationType); + } +} + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + ResolveVertexDataArray(normals_out,source,MappingInformationType,ReferenceInformationType, + "Normals", + "NormalsIndex", + vertices.size(), + mapping_counts, + mapping_offsets, + mappings); +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + ResolveVertexDataArray(uv_out,source,MappingInformationType,ReferenceInformationType, + "UV", + "UVIndex", + vertices.size(), + mapping_counts, + mapping_offsets, + mappings); +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + ResolveVertexDataArray(colors_out,source,MappingInformationType,ReferenceInformationType, + "Colors", + "ColorIndex", + vertices.size(), + mapping_counts, + mapping_offsets, + mappings); +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType, + "Tangent", + "TangentIndex", + vertices.size(), + mapping_counts, + mapping_offsets, + mappings); +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType, + "Binormal", + "BinormalIndex", + vertices.size(), + mapping_counts, + mapping_offsets, + mappings); +} + + +// ------------------------------------------------------------------------------------------------ +void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, const Scope& source, + const std::string& MappingInformationType, + const std::string& ReferenceInformationType) +{ + const size_t face_count = faces.size(); + ai_assert(face_count); + + // materials are handled separately. First of all, they are assigned per-face + // and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect + // has a slightly different meaning for materials. + ParseVectorDataArray(materials_out,GetRequiredElement(source,"Materials")); + + if (MappingInformationType == "AllSame") { + // easy - same material for all faces + if (materials_out.empty()) { + FBXImporter::LogError(Formatter::format("expected material index, ignoring")); + return; + } + else if (materials_out.size() > 1) { + FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one")); + materials_out.clear(); + } + + materials.assign(vertices.size(),materials_out[0]); + } + else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") { + materials.resize(face_count); + + if(materials_out.size() != face_count) { + FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ") + << materials_out.size() << ", expected " << face_count + ); + return; + } + } + else { + FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ") + << MappingInformationType << "," << ReferenceInformationType); + } +} + +} // !FBX +} // !Assimp + +#endif + diff --git a/src/3rdparty/assimp/code/FBXModel.cpp b/src/3rdparty/assimp/code/FBXModel.cpp new file mode 100644 index 000000000..d6d329801 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXModel.cpp @@ -0,0 +1,156 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXModel.cpp + * @brief Assimp::FBX::Model implementation + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXImporter.h" +#include "FBXImportSettings.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + +// ------------------------------------------------------------------------------------------------ +Model::Model(uint64_t id, const Element& element, const Document& doc, const std::string& name) + : Object(id,element,name) + , shading("Y") +{ + const Scope& sc = GetRequiredScope(element); + const Element* const Shading = sc["Shading"]; + const Element* const Culling = sc["Culling"]; + + if(Shading) { + shading = GetRequiredToken(*Shading,0).StringContents(); + } + + if (Culling) { + culling = ParseTokenAsString(GetRequiredToken(*Culling,0)); + } + + props = GetPropertyTable(doc,"Model.FbxNode",element,sc); + ResolveLinks(element,doc); +} + + +// ------------------------------------------------------------------------------------------------ +Model::~Model() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +void Model::ResolveLinks(const Element& element, const Document& doc) +{ + const char* const arr[] = {"Geometry","Material","NodeAttribute"}; + + // resolve material + const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),arr, 3); + + materials.reserve(conns.size()); + geometry.reserve(conns.size()); + attributes.reserve(conns.size()); + BOOST_FOREACH(const Connection* con, conns) { + + // material and geometry links should be Object-Object connections + if (con->PropertyName().length()) { + continue; + } + + const Object* const ob = con->SourceObject(); + if(!ob) { + DOMWarning("failed to read source object for incoming Model link, ignoring",&element); + continue; + } + + const Material* const mat = dynamic_cast<const Material*>(ob); + if(mat) { + materials.push_back(mat); + continue; + } + + const Geometry* const geo = dynamic_cast<const Geometry*>(ob); + if(geo) { + geometry.push_back(geo); + continue; + } + + const NodeAttribute* const att = dynamic_cast<const NodeAttribute*>(ob); + if(att) { + attributes.push_back(att); + continue; + } + + DOMWarning("source object for model link is neither Material, NodeAttribute nor Geometry, ignoring",&element); + continue; + } +} + + +// ------------------------------------------------------------------------------------------------ +bool Model::IsNull() const +{ + const std::vector<const NodeAttribute*>& attrs = GetAttributes(); + BOOST_FOREACH(const NodeAttribute* att, attrs) { + + const Null* null_tag = dynamic_cast<const Null*>(att); + if(null_tag) { + return true; + } + } + + return false; +} + + +} //!FBX +} //!Assimp + +#endif diff --git a/src/3rdparty/assimp/code/FBXNodeAttribute.cpp b/src/3rdparty/assimp/code/FBXNodeAttribute.cpp new file mode 100644 index 000000000..1b7314666 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXNodeAttribute.cpp @@ -0,0 +1,173 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXNoteAttribute.cpp + * @brief Assimp::FBX::NodeAttribute (and subclasses) implementation + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXImporter.h" +#include "FBXImportSettings.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + +// ------------------------------------------------------------------------------------------------ +NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name) + : Object(id,element,name) +{ + const Scope& sc = GetRequiredScope(element); + + const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2)); + + // hack on the deriving type but Null/LimbNode attributes are the only case in which + // the property table is by design absent and no warning should be generated + // for it. + const bool is_null_or_limb = !strcmp(classname.c_str(), "Null") || !strcmp(classname.c_str(), "LimbNode"); + props = GetPropertyTable(doc,"NodeAttribute.Fbx" + classname,element,sc, is_null_or_limb); +} + + +// ------------------------------------------------------------------------------------------------ +NodeAttribute::~NodeAttribute() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name) + : NodeAttribute(id,element,doc,name) +{ + const Scope& sc = GetRequiredScope(element); + const Element* const CameraId = sc["CameraId"]; + const Element* const CameraName = sc["CameraName"]; + const Element* const CameraIndexName = sc["CameraIndexName"]; + + if(CameraId) { + cameraId = ParseTokenAsInt(GetRequiredToken(*CameraId,0)); + } + + if(CameraName) { + cameraName = GetRequiredToken(*CameraName,0).StringContents(); + } + + if(CameraIndexName && CameraIndexName->Tokens().size()) { + cameraIndexName = GetRequiredToken(*CameraIndexName,0).StringContents(); + } +} + + +// ------------------------------------------------------------------------------------------------ +CameraSwitcher::~CameraSwitcher() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: NodeAttribute(id,element,doc,name) +{ + +} + + +// ------------------------------------------------------------------------------------------------ +Camera::~Camera() +{ +} + + +// ------------------------------------------------------------------------------------------------ +Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: NodeAttribute(id,element,doc,name) +{ + +} + + +// ------------------------------------------------------------------------------------------------ +Light::~Light() +{ +} + + +// ------------------------------------------------------------------------------------------------ +Null::Null(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: NodeAttribute(id,element,doc,name) +{ + +} + + +// ------------------------------------------------------------------------------------------------ +Null::~Null() +{ + +} + + +// ------------------------------------------------------------------------------------------------ +LimbNode::LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name) +: NodeAttribute(id,element,doc,name) +{ + +} + + +// ------------------------------------------------------------------------------------------------ +LimbNode::~LimbNode() +{ + +} + +} +} + +#endif diff --git a/src/3rdparty/assimp/code/FBXParser.cpp b/src/3rdparty/assimp/code/FBXParser.cpp new file mode 100644 index 000000000..fce1143fd --- /dev/null +++ b/src/3rdparty/assimp/code/FBXParser.cpp @@ -0,0 +1,1208 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXParser.cpp + * @brief Implementation of the FBX parser and the rudimentary DOM that we use + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + + +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +# include <zlib.h> +#else +# include "../contrib/zlib/zlib.h" +#endif + + +#include "FBXTokenizer.h" +#include "FBXParser.h" +#include "FBXUtil.h" + +#include "ParsingUtils.h" +#include "fast_atof.h" + +using namespace Assimp; +using namespace Assimp::FBX; + +namespace { + + + // ------------------------------------------------------------------------------------------------ + // signal parse error, this is always unrecoverable. Throws DeadlyImportError. + void ParseError(const std::string& message, const Token& token) + { + throw DeadlyImportError(Util::AddTokenText("FBX-Parser",message,&token)); + } + + // ------------------------------------------------------------------------------------------------ + void ParseError(const std::string& message, const Element* element = NULL) + { + if(element) { + ParseError(message,element->KeyToken()); + } + throw DeadlyImportError("FBX-Parser " + message); + } + + + // ------------------------------------------------------------------------------------------------ + // print warning, do return + void ParseWarning(const std::string& message, const Token& token) + { + if(DefaultLogger::get()) { + DefaultLogger::get()->warn(Util::AddTokenText("FBX-Parser",message,&token)); + } + } + + // ------------------------------------------------------------------------------------------------ + void ParseWarning(const std::string& message, const Element* element = NULL) + { + if(element) { + ParseWarning(message,element->KeyToken()); + return; + } + if(DefaultLogger::get()) { + DefaultLogger::get()->warn("FBX-Parser: " + message); + } + } + + // ------------------------------------------------------------------------------------------------ + void ParseError(const std::string& message, TokenPtr token) + { + if(token) { + ParseError(message, *token); + } + ParseError(message); + } + +} + +namespace Assimp { +namespace FBX { + +// ------------------------------------------------------------------------------------------------ +Element::Element(const Token& key_token, Parser& parser) +: key_token(key_token) +{ + TokenPtr n = NULL; + do { + n = parser.AdvanceToNextToken(); + if(!n) { + ParseError("unexpected end of file, expected closing bracket",parser.LastToken()); + } + + if (n->Type() == TokenType_DATA) { + tokens.push_back(n); + + n = parser.AdvanceToNextToken(); + if(!n) { + ParseError("unexpected end of file, expected bracket, comma or key",parser.LastToken()); + } + + const TokenType ty = n->Type(); + if (ty != TokenType_OPEN_BRACKET && ty != TokenType_CLOSE_BRACKET && ty != TokenType_COMMA && ty != TokenType_KEY) { + ParseError("unexpected token; expected bracket, comma or key",n); + } + } + + if (n->Type() == TokenType_OPEN_BRACKET) { + compound.reset(new Scope(parser)); + + // current token should be a TOK_CLOSE_BRACKET + n = parser.CurrentToken(); + ai_assert(n); + + if (n->Type() != TokenType_CLOSE_BRACKET) { + ParseError("expected closing bracket",n); + } + + parser.AdvanceToNextToken(); + return; + } + } + while(n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET); +} + +// ------------------------------------------------------------------------------------------------ +Element::~Element() +{ + // no need to delete tokens, they are owned by the parser +} + +// ------------------------------------------------------------------------------------------------ +Scope::Scope(Parser& parser,bool topLevel) +{ + if(!topLevel) { + TokenPtr t = parser.CurrentToken(); + if (t->Type() != TokenType_OPEN_BRACKET) { + ParseError("expected open bracket",t); + } + } + + TokenPtr n = parser.AdvanceToNextToken(); + if(n == NULL) { + ParseError("unexpected end of file"); + } + + // note: empty scopes are allowed + while(n->Type() != TokenType_CLOSE_BRACKET) { + if (n->Type() != TokenType_KEY) { + ParseError("unexpected token, expected TOK_KEY",n); + } + + const std::string& str = n->StringContents(); + elements.insert(ElementMap::value_type(str,new_Element(*n,parser))); + + // Element() should stop at the next Key token (or right after a Close token) + n = parser.CurrentToken(); + if(n == NULL) { + if (topLevel) { + return; + } + ParseError("unexpected end of file",parser.LastToken()); + } + } +} + +// ------------------------------------------------------------------------------------------------ +Scope::~Scope() +{ + BOOST_FOREACH(ElementMap::value_type& v, elements) { + delete v.second; + } +} + + +// ------------------------------------------------------------------------------------------------ +Parser::Parser (const TokenList& tokens, bool is_binary) +: tokens(tokens) +, last() +, current() +, cursor(tokens.begin()) +, is_binary(is_binary) +{ + root.reset(new Scope(*this,true)); +} + + +// ------------------------------------------------------------------------------------------------ +Parser::~Parser() +{ +} + + +// ------------------------------------------------------------------------------------------------ +TokenPtr Parser::AdvanceToNextToken() +{ + last = current; + if (cursor == tokens.end()) { + current = NULL; + } + else { + current = *cursor++; + } + return current; +} + + +// ------------------------------------------------------------------------------------------------ +TokenPtr Parser::CurrentToken() const +{ + return current; +} + + +// ------------------------------------------------------------------------------------------------ +TokenPtr Parser::LastToken() const +{ + return last; +} + + +// ------------------------------------------------------------------------------------------------ +uint64_t ParseTokenAsID(const Token& t, const char*& err_out) +{ + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return 0L; + } + + if(t.IsBinary()) + { + const char* data = t.begin(); + if (data[0] != 'L') { + err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)"; + return 0L; + } + + ai_assert(t.end() - data == 9); + + BE_NCONST uint64_t id = *reinterpret_cast<const uint64_t*>(data+1); + AI_SWAP8(id); + return id; + } + + // XXX: should use size_t here + unsigned int length = static_cast<unsigned int>(t.end() - t.begin()); + ai_assert(length > 0); + + const char* out; + const uint64_t id = strtoul10_64(t.begin(),&out,&length); + if (out > t.end()) { + err_out = "failed to parse ID (text)"; + return 0L; + } + + return id; +} + + +// ------------------------------------------------------------------------------------------------ +size_t ParseTokenAsDim(const Token& t, const char*& err_out) +{ + // same as ID parsing, except there is a trailing asterisk + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return 0; + } + + if(t.IsBinary()) + { + const char* data = t.begin(); + if (data[0] != 'L') { + err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)"; + return 0; + } + + ai_assert(t.end() - data == 9); + BE_NCONST uint64_t id = *reinterpret_cast<const uint64_t*>(data+1); + AI_SWAP8(id); + return static_cast<size_t>(id); + } + + if(*t.begin() != '*') { + err_out = "expected asterisk before array dimension"; + return 0; + } + + // XXX: should use size_t here + unsigned int length = static_cast<unsigned int>(t.end() - t.begin()); + if(length == 0) { + err_out = "expected valid integer number after asterisk"; + return 0; + } + + const char* out; + const size_t id = static_cast<size_t>(strtoul10_64(t.begin() + 1,&out,&length)); + if (out > t.end()) { + err_out = "failed to parse ID"; + return 0; + } + + return id; +} + + +// ------------------------------------------------------------------------------------------------ +float ParseTokenAsFloat(const Token& t, const char*& err_out) +{ + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return 0.0f; + } + + if(t.IsBinary()) + { + const char* data = t.begin(); + if (data[0] != 'F' && data[0] != 'D') { + err_out = "failed to parse F(loat) or D(ouble), unexpected data type (binary)"; + return 0.0f; + } + + if (data[0] == 'F') { + ai_assert(t.end() - data == 5); + // no byte swapping needed for ieee floats + return *reinterpret_cast<const float*>(data+1); + } + else { + ai_assert(t.end() - data == 9); + // no byte swapping needed for ieee floats + return static_cast<float>(*reinterpret_cast<const double*>(data+1)); + } + } + + // need to copy the input string to a temporary buffer + // first - next in the fbx token stream comes ',', + // which fast_atof could interpret as decimal point. +#define MAX_FLOAT_LENGTH 31 + char temp[MAX_FLOAT_LENGTH + 1]; + const size_t length = static_cast<size_t>(t.end()-t.begin()); + std::copy(t.begin(),t.end(),temp); + temp[std::min(static_cast<size_t>(MAX_FLOAT_LENGTH),length)] = '\0'; + + return fast_atof(temp); +} + + +// ------------------------------------------------------------------------------------------------ +int ParseTokenAsInt(const Token& t, const char*& err_out) +{ + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return 0; + } + + if(t.IsBinary()) + { + const char* data = t.begin(); + if (data[0] != 'I') { + err_out = "failed to parse I(nt), unexpected data type (binary)"; + return 0; + } + + ai_assert(t.end() - data == 5); + BE_NCONST int32_t ival = *reinterpret_cast<const int32_t*>(data+1); + AI_SWAP4(ival); + return static_cast<int>(ival); + } + + ai_assert(static_cast<size_t>(t.end() - t.begin()) > 0); + + const char* out; + const int intval = strtol10(t.begin(),&out); + if (out != t.end()) { + err_out = "failed to parse ID"; + return 0; + } + + return intval; +} + + +// ------------------------------------------------------------------------------------------------ +std::string ParseTokenAsString(const Token& t, const char*& err_out) +{ + err_out = NULL; + + if (t.Type() != TokenType_DATA) { + err_out = "expected TOK_DATA token"; + return ""; + } + + if(t.IsBinary()) + { + const char* data = t.begin(); + if (data[0] != 'S') { + err_out = "failed to parse S(tring), unexpected data type (binary)"; + return ""; + } + + ai_assert(t.end() - data >= 5); + + // read string length + BE_NCONST int32_t len = *reinterpret_cast<const int32_t*>(data+1); + AI_SWAP4(len); + + ai_assert(t.end() - data == 5 + len); + return std::string(data + 5, len); + } + + const size_t length = static_cast<size_t>(t.end() - t.begin()); + if(length < 2) { + err_out = "token is too short to hold a string"; + return ""; + } + + const char* s = t.begin(), *e = t.end() - 1; + if (*s != '\"' || *e != '\"') { + err_out = "expected double quoted string"; + return ""; + } + + return std::string(s+1,length-2); +} + + +namespace { + +// ------------------------------------------------------------------------------------------------ +// read the type code and element count of a binary data array and stop there +void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uint32_t& count, + const Element& el) +{ + if (static_cast<size_t>(end-data) < 5) { + ParseError("binary data array is too short, need five (5) bytes for type signature and element count",&el); + } + + // data type + type = *data; + + // read number of elements + BE_NCONST uint32_t len = *reinterpret_cast<const uint32_t*>(data+1); + AI_SWAP4(len); + + count = len; + data += 5; +} + + +// ------------------------------------------------------------------------------------------------ +// read binary data array, assume cursor points to the 'compression mode' field (i.e. behind the header) +void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end, + std::vector<char>& buff, + const Element& el) +{ + ai_assert(static_cast<size_t>(end-data) >= 4); // runtime check for this happens at tokenization stage + + BE_NCONST uint32_t encmode = *reinterpret_cast<const uint32_t*>(data); + AI_SWAP4(encmode); + data += 4; + + // next comes the compressed length + BE_NCONST uint32_t comp_len = *reinterpret_cast<const uint32_t*>(data); + AI_SWAP4(comp_len); + data += 4; + + ai_assert(data + comp_len == end); + + // determine the length of the uncompressed data by looking at the type signature + uint32_t stride = 0; + switch(type) + { + case 'f': + case 'i': + stride = 4; + break; + + case 'd': + case 'l': + stride = 8; + break; + + default: + ai_assert(false); + }; + + const uint32_t full_length = stride * count; + buff.resize(full_length); + + if(encmode == 0) { + ai_assert(full_length == comp_len); + + // plain data, no compression + std::copy(data, end, buff.begin()); + } + else if(encmode == 1) { + // zlib/deflate, next comes ZIP head (0x78 0x01) + // see http://www.ietf.org/rfc/rfc1950.txt + + z_stream zstream; + zstream.opaque = Z_NULL; + zstream.zalloc = Z_NULL; + zstream.zfree = Z_NULL; + zstream.data_type = Z_BINARY; + + // http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib + inflateInit(&zstream); + + zstream.next_in = reinterpret_cast<Bytef*>( const_cast<char*>(data) ); + zstream.avail_in = comp_len; + + zstream.avail_out = buff.size(); + zstream.next_out = reinterpret_cast<Bytef*>(&*buff.begin()); + const int ret = inflate(&zstream, Z_FINISH); + + if (ret != Z_STREAM_END && ret != Z_OK) { + ParseError("failure decompressing compressed data section"); + } + + // terminate zlib + inflateEnd(&zstream); + } +#ifdef ASSIMP_BUILD_DEBUG + else { + // runtime check for this happens at tokenization stage + ai_assert(false); + } +#endif + + data += comp_len; + ai_assert(data == end); +} + +} // !anon + + +// ------------------------------------------------------------------------------------------------ +// read an array of float3 tuples +void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el) +{ + out.clear(); + + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + ParseError("unexpected empty element",&el); + } + + if(tok[0]->IsBinary()) { + const char* data = tok[0]->begin(), *end = tok[0]->end(); + + char type; + uint32_t count; + ReadBinaryDataArrayHead(data, end, type, count, el); + + if(count % 3 != 0) { + ParseError("number of floats is not a multiple of three (3) (binary)",&el); + } + + if(!count) { + return; + } + + if (type != 'd' && type != 'f') { + ParseError("expected float or double array (binary)",&el); + } + + std::vector<char> buff; + ReadBinaryDataArray(type, count, data, end, buff, el); + + ai_assert(data == end); + ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); + + const uint32_t count3 = count / 3; + out.reserve(count3); + + if (type == 'd') { + const double* d = reinterpret_cast<const double*>(&buff[0]); + for (unsigned int i = 0; i < count3; ++i, d += 3) { + out.push_back(aiVector3D(static_cast<float>(d[0]), + static_cast<float>(d[1]), + static_cast<float>(d[2]))); + } + } + else if (type == 'f') { + const float* f = reinterpret_cast<const float*>(&buff[0]); + for (unsigned int i = 0; i < count3; ++i, f += 3) { + out.push_back(aiVector3D(f[0],f[1],f[2])); + } + } + + return; + } + + const size_t dim = ParseTokenAsDim(*tok[0]); + + // may throw bad_alloc if the input is rubbish, but this need + // not to be prevented - importing would fail but we wouldn't + // crash since assimp handles this case properly. + out.reserve(dim); + + const Scope& scope = GetRequiredScope(el); + const Element& a = GetRequiredElement(scope,"a",&el); + + if (a.Tokens().size() % 3 != 0) { + ParseError("number of floats is not a multiple of three (3)",&el); + } + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + aiVector3D v; + v.x = ParseTokenAsFloat(**it++); + v.y = ParseTokenAsFloat(**it++); + v.z = ParseTokenAsFloat(**it++); + + out.push_back(v); + } +} + + +// ------------------------------------------------------------------------------------------------ +// read an array of color4 tuples +void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el) +{ + out.clear(); + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + ParseError("unexpected empty element",&el); + } + + if(tok[0]->IsBinary()) { + const char* data = tok[0]->begin(), *end = tok[0]->end(); + + char type; + uint32_t count; + ReadBinaryDataArrayHead(data, end, type, count, el); + + if(count % 4 != 0) { + ParseError("number of floats is not a multiple of four (4) (binary)",&el); + } + + if(!count) { + return; + } + + if (type != 'd' && type != 'f') { + ParseError("expected float or double array (binary)",&el); + } + + std::vector<char> buff; + ReadBinaryDataArray(type, count, data, end, buff, el); + + ai_assert(data == end); + ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); + + const uint32_t count4 = count / 4; + out.reserve(count4); + + if (type == 'd') { + const double* d = reinterpret_cast<const double*>(&buff[0]); + for (unsigned int i = 0; i < count4; ++i, d += 4) { + out.push_back(aiColor4D(static_cast<float>(d[0]), + static_cast<float>(d[1]), + static_cast<float>(d[2]), + static_cast<float>(d[3]))); + } + } + else if (type == 'f') { + const float* f = reinterpret_cast<const float*>(&buff[0]); + for (unsigned int i = 0; i < count4; ++i, f += 4) { + out.push_back(aiColor4D(f[0],f[1],f[2],f[3])); + } + } + return; + } + + const size_t dim = ParseTokenAsDim(*tok[0]); + + // see notes in ParseVectorDataArray() above + out.reserve(dim); + + const Scope& scope = GetRequiredScope(el); + const Element& a = GetRequiredElement(scope,"a",&el); + + if (a.Tokens().size() % 4 != 0) { + ParseError("number of floats is not a multiple of four (4)",&el); + } + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + aiColor4D v; + v.r = ParseTokenAsFloat(**it++); + v.g = ParseTokenAsFloat(**it++); + v.b = ParseTokenAsFloat(**it++); + v.a = ParseTokenAsFloat(**it++); + + out.push_back(v); + } +} + + +// ------------------------------------------------------------------------------------------------ +// read an array of float2 tuples +void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) +{ + out.clear(); + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + ParseError("unexpected empty element",&el); + } + + if(tok[0]->IsBinary()) { + const char* data = tok[0]->begin(), *end = tok[0]->end(); + + char type; + uint32_t count; + ReadBinaryDataArrayHead(data, end, type, count, el); + + if(count % 2 != 0) { + ParseError("number of floats is not a multiple of two (2) (binary)",&el); + } + + if(!count) { + return; + } + + if (type != 'd' && type != 'f') { + ParseError("expected float or double array (binary)",&el); + } + + std::vector<char> buff; + ReadBinaryDataArray(type, count, data, end, buff, el); + + ai_assert(data == end); + ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); + + const uint32_t count2 = count / 2; + out.reserve(count2); + + if (type == 'd') { + const double* d = reinterpret_cast<const double*>(&buff[0]); + for (unsigned int i = 0; i < count2; ++i, d += 2) { + out.push_back(aiVector2D(static_cast<float>(d[0]), + static_cast<float>(d[1]))); + } + } + else if (type == 'f') { + const float* f = reinterpret_cast<const float*>(&buff[0]); + for (unsigned int i = 0; i < count2; ++i, f += 2) { + out.push_back(aiVector2D(f[0],f[1])); + } + } + + return; + } + + const size_t dim = ParseTokenAsDim(*tok[0]); + + // see notes in ParseVectorDataArray() above + out.reserve(dim); + + const Scope& scope = GetRequiredScope(el); + const Element& a = GetRequiredElement(scope,"a",&el); + + if (a.Tokens().size() % 2 != 0) { + ParseError("number of floats is not a multiple of two (2)",&el); + } + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + aiVector2D v; + v.x = ParseTokenAsFloat(**it++); + v.y = ParseTokenAsFloat(**it++); + + out.push_back(v); + } +} + + +// ------------------------------------------------------------------------------------------------ +// read an array of ints +void ParseVectorDataArray(std::vector<int>& out, const Element& el) +{ + out.clear(); + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + ParseError("unexpected empty element",&el); + } + + if(tok[0]->IsBinary()) { + const char* data = tok[0]->begin(), *end = tok[0]->end(); + + char type; + uint32_t count; + ReadBinaryDataArrayHead(data, end, type, count, el); + + if(!count) { + return; + } + + if (type != 'i') { + ParseError("expected int array (binary)",&el); + } + + std::vector<char> buff; + ReadBinaryDataArray(type, count, data, end, buff, el); + + ai_assert(data == end); + ai_assert(buff.size() == count * 4); + + out.reserve(count); + + const int32_t* ip = reinterpret_cast<const int32_t*>(&buff[0]); + for (unsigned int i = 0; i < count; ++i, ++ip) { + BE_NCONST int32_t val = *ip; + AI_SWAP4(val); + out.push_back(val); + } + + return; + } + + const size_t dim = ParseTokenAsDim(*tok[0]); + + // see notes in ParseVectorDataArray() + out.reserve(dim); + + const Scope& scope = GetRequiredScope(el); + const Element& a = GetRequiredElement(scope,"a",&el); + + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + const int ival = ParseTokenAsInt(**it++); + out.push_back(ival); + } +} + + +// ------------------------------------------------------------------------------------------------ +// read an array of floats +void ParseVectorDataArray(std::vector<float>& out, const Element& el) +{ + out.clear(); + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + ParseError("unexpected empty element",&el); + } + + if(tok[0]->IsBinary()) { + const char* data = tok[0]->begin(), *end = tok[0]->end(); + + char type; + uint32_t count; + ReadBinaryDataArrayHead(data, end, type, count, el); + + if(!count) { + return; + } + + if (type != 'd' && type != 'f') { + ParseError("expected float or double array (binary)",&el); + } + + std::vector<char> buff; + ReadBinaryDataArray(type, count, data, end, buff, el); + + ai_assert(data == end); + ai_assert(buff.size() == count * (type == 'd' ? 8 : 4)); + + if (type == 'd') { + const double* d = reinterpret_cast<const double*>(&buff[0]); + for (unsigned int i = 0; i < count; ++i, ++d) { + out.push_back(static_cast<float>(*d)); + } + } + else if (type == 'f') { + const float* f = reinterpret_cast<const float*>(&buff[0]); + for (unsigned int i = 0; i < count; ++i, ++f) { + out.push_back(*f); + } + } + + return; + } + + const size_t dim = ParseTokenAsDim(*tok[0]); + + // see notes in ParseVectorDataArray() + out.reserve(dim); + + const Scope& scope = GetRequiredScope(el); + const Element& a = GetRequiredElement(scope,"a",&el); + + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + const float ival = ParseTokenAsFloat(**it++); + out.push_back(ival); + } +} + + +// ------------------------------------------------------------------------------------------------ +// read an array of uints +void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el) +{ + out.clear(); + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + ParseError("unexpected empty element",&el); + } + + if(tok[0]->IsBinary()) { + const char* data = tok[0]->begin(), *end = tok[0]->end(); + + char type; + uint32_t count; + ReadBinaryDataArrayHead(data, end, type, count, el); + + if(!count) { + return; + } + + if (type != 'i') { + ParseError("expected (u)int array (binary)",&el); + } + + std::vector<char> buff; + ReadBinaryDataArray(type, count, data, end, buff, el); + + ai_assert(data == end); + ai_assert(buff.size() == count * 4); + + out.reserve(count); + + const int32_t* ip = reinterpret_cast<const int32_t*>(&buff[0]); + for (unsigned int i = 0; i < count; ++i, ++ip) { + BE_NCONST int32_t val = *ip; + if(val < 0) { + ParseError("encountered negative integer index (binary)"); + } + + AI_SWAP4(val); + out.push_back(val); + } + + return; + } + + const size_t dim = ParseTokenAsDim(*tok[0]); + + // see notes in ParseVectorDataArray() + out.reserve(dim); + + const Scope& scope = GetRequiredScope(el); + const Element& a = GetRequiredElement(scope,"a",&el); + + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + const int ival = ParseTokenAsInt(**it++); + if(ival < 0) { + ParseError("encountered negative integer index"); + } + out.push_back(static_cast<unsigned int>(ival)); + } +} + + +// ------------------------------------------------------------------------------------------------ +// read an array of uint64_ts +void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el) +{ + out.clear(); + const TokenList& tok = el.Tokens(); + if(tok.empty()) { + ParseError("unexpected empty element",&el); + } + + if(tok[0]->IsBinary()) { + const char* data = tok[0]->begin(), *end = tok[0]->end(); + + char type; + uint32_t count; + ReadBinaryDataArrayHead(data, end, type, count, el); + + if(!count) { + return; + } + + if (type != 'l') { + ParseError("expected long array (binary)",&el); + } + + std::vector<char> buff; + ReadBinaryDataArray(type, count, data, end, buff, el); + + ai_assert(data == end); + ai_assert(buff.size() == count * 8); + + out.reserve(count); + + const uint64_t* ip = reinterpret_cast<const uint64_t*>(&buff[0]); + for (unsigned int i = 0; i < count; ++i, ++ip) { + BE_NCONST uint64_t val = *ip; + AI_SWAP8(val); + out.push_back(val); + } + + return; + } + + const size_t dim = ParseTokenAsDim(*tok[0]); + + // see notes in ParseVectorDataArray() + out.reserve(dim); + + const Scope& scope = GetRequiredScope(el); + const Element& a = GetRequiredElement(scope,"a",&el); + + for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) { + const uint64_t ival = ParseTokenAsID(**it++); + + out.push_back(ival); + } +} + + +// ------------------------------------------------------------------------------------------------ +aiMatrix4x4 ReadMatrix(const Element& element) +{ + std::vector<float> values; + ParseVectorDataArray(values,element); + + if(values.size() != 16) { + ParseError("expected 16 matrix elements"); + } + + aiMatrix4x4 result; + + + result.a1 = values[0]; + result.a2 = values[1]; + result.a3 = values[2]; + result.a4 = values[3]; + + result.b1 = values[4]; + result.b2 = values[5]; + result.b3 = values[6]; + result.b4 = values[7]; + + result.c1 = values[8]; + result.c2 = values[9]; + result.c3 = values[10]; + result.c4 = values[11]; + + result.d1 = values[12]; + result.d2 = values[13]; + result.d3 = values[14]; + result.d4 = values[15]; + + result.Transpose(); + return result; +} + + +// ------------------------------------------------------------------------------------------------ +// wrapper around ParseTokenAsString() with ParseError handling +std::string ParseTokenAsString(const Token& t) +{ + const char* err; + const std::string& i = ParseTokenAsString(t,err); + if(err) { + ParseError(err,t); + } + return i; +} + + +// ------------------------------------------------------------------------------------------------ +// extract a required element from a scope, abort if the element cannot be found +const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= NULL*/) +{ + const Element* el = sc[index]; + if(!el) { + ParseError("did not find required element \"" + index + "\"",element); + } + return *el; +} + + +// ------------------------------------------------------------------------------------------------ +// extract required compound scope +const Scope& GetRequiredScope(const Element& el) +{ + const Scope* const s = el.Compound(); + if(!s) { + ParseError("expected compound scope",&el); + } + + return *s; +} + + +// ------------------------------------------------------------------------------------------------ +// get token at a particular index +const Token& GetRequiredToken(const Element& el, unsigned int index) +{ + const TokenList& t = el.Tokens(); + if(index >= t.size()) { + ParseError(Formatter::format( "missing token at index " ) << index,&el); + } + + return *t[index]; +} + + +// ------------------------------------------------------------------------------------------------ +// wrapper around ParseTokenAsID() with ParseError handling +uint64_t ParseTokenAsID(const Token& t) +{ + const char* err; + const uint64_t i = ParseTokenAsID(t,err); + if(err) { + ParseError(err,t); + } + return i; +} + + +// ------------------------------------------------------------------------------------------------ +// wrapper around ParseTokenAsDim() with ParseError handling +size_t ParseTokenAsDim(const Token& t) +{ + const char* err; + const size_t i = ParseTokenAsDim(t,err); + if(err) { + ParseError(err,t); + } + return i; +} + + +// ------------------------------------------------------------------------------------------------ +// wrapper around ParseTokenAsFloat() with ParseError handling +float ParseTokenAsFloat(const Token& t) +{ + const char* err; + const float i = ParseTokenAsFloat(t,err); + if(err) { + ParseError(err,t); + } + return i; +} + + +// ------------------------------------------------------------------------------------------------ +// wrapper around ParseTokenAsInt() with ParseError handling +int ParseTokenAsInt(const Token& t) +{ + const char* err; + const int i = ParseTokenAsInt(t,err); + if(err) { + ParseError(err,t); + } + return i; +} + + + +} // !FBX +} // !Assimp + +#endif + diff --git a/src/3rdparty/assimp/code/FBXParser.h b/src/3rdparty/assimp/code/FBXParser.h new file mode 100644 index 000000000..e6fa25d22 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXParser.h @@ -0,0 +1,246 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXParser.h + * @brief FBX parsing code + */ +#ifndef INCLUDED_AI_FBX_PARSER_H +#define INCLUDED_AI_FBX_PARSER_H + +#include <vector> +#include <map> +#include <string> +#include <utility> + +#include <boost/shared_ptr.hpp> + +#include "LogAux.h" + +#include "FBXCompileConfig.h" +#include "FBXTokenizer.h" + +namespace Assimp { +namespace FBX { + + class Scope; + class Parser; + class Element; + + // XXX should use C++11's unique_ptr - but assimp's need to keep working with 03 + typedef std::vector< Scope* > ScopeList; + typedef std::fbx_unordered_multimap< std::string, Element* > ElementMap; + + typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> ElementCollection; + +# define new_Scope new Scope +# define new_Element new Element + + +/** FBX data entity that consists of a key:value tuple. + * + * Example: + * @verbatim + * AnimationCurve: 23, "AnimCurve::", "" { + * [..] + * } + * @endverbatim + * + * As can be seen in this sample, elements can contain nested #Scope + * as their trailing member. **/ +class Element +{ +public: + + Element(const Token& key_token, Parser& parser); + ~Element(); + +public: + + const Scope* Compound() const { + return compound.get(); + } + + const Token& KeyToken() const { + return key_token; + } + + const TokenList& Tokens() const { + return tokens; + } + +private: + + const Token& key_token; + TokenList tokens; + boost::scoped_ptr<Scope> compound; +}; + + + +/** FBX data entity that consists of a 'scope', a collection + * of not necessarily unique #Element instances. + * + * Example: + * @verbatim + * GlobalSettings: { + * Version: 1000 + * Properties70: + * [...] + * } + * @endverbatim */ +class Scope +{ + +public: + + Scope(Parser& parser, bool topLevel = false); + ~Scope(); + +public: + + const Element* operator[] (const std::string& index) const { + ElementMap::const_iterator it = elements.find(index); + return it == elements.end() ? NULL : (*it).second; + } + + ElementCollection GetCollection(const std::string& index) const { + return elements.equal_range(index); + } + + const ElementMap& Elements() const { + return elements; + } + +private: + + ElementMap elements; +}; + + +/** FBX parsing class, takes a list of input tokens and generates a hierarchy + * of nested #Scope instances, representing the fbx DOM.*/ +class Parser +{ +public: + + /** Parse given a token list. Does not take ownership of the tokens - + * the objects must persist during the entire parser lifetime */ + Parser (const TokenList& tokens,bool is_binary); + ~Parser(); + +public: + + const Scope& GetRootScope() const { + return *root.get(); + } + + + bool IsBinary() const { + return is_binary; + } + +private: + + friend class Scope; + friend class Element; + + TokenPtr AdvanceToNextToken(); + + TokenPtr LastToken() const; + TokenPtr CurrentToken() const; + + + +private: + + const TokenList& tokens; + + TokenPtr last, current; + TokenList::const_iterator cursor; + boost::scoped_ptr<Scope> root; + + const bool is_binary; +}; + + +/* token parsing - this happens when building the DOM out of the parse-tree*/ +uint64_t ParseTokenAsID(const Token& t, const char*& err_out); +size_t ParseTokenAsDim(const Token& t, const char*& err_out); + +float ParseTokenAsFloat(const Token& t, const char*& err_out); +int ParseTokenAsInt(const Token& t, const char*& err_out); +std::string ParseTokenAsString(const Token& t, const char*& err_out); + + +/* wrapper around ParseTokenAsXXX() with DOMError handling */ +uint64_t ParseTokenAsID(const Token& t); +size_t ParseTokenAsDim(const Token& t); +float ParseTokenAsFloat(const Token& t); +int ParseTokenAsInt(const Token& t); +std::string ParseTokenAsString(const Token& t); + +/* read data arrays */ +void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el); +void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el); +void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el); +void ParseVectorDataArray(std::vector<int>& out, const Element& el); +void ParseVectorDataArray(std::vector<float>& out, const Element& el); +void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el); +void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e); + + + +// extract a required element from a scope, abort if the element cannot be found +const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL); + +// extract required compound scope +const Scope& GetRequiredScope(const Element& el); +// get token at a particular index +const Token& GetRequiredToken(const Element& el, unsigned int index); + + + +// read a 4x4 matrix from an array of 16 floats +aiMatrix4x4 ReadMatrix(const Element& element); + +} // ! FBX +} // ! Assimp + +#endif // ! INCLUDED_AI_FBX_PARSER_H diff --git a/src/3rdparty/assimp/code/FBXProperties.cpp b/src/3rdparty/assimp/code/FBXProperties.cpp new file mode 100644 index 000000000..48bdb4f40 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXProperties.cpp @@ -0,0 +1,234 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXProperties.cpp + * @brief Implementation of the FBX dynamic properties system + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +#include "FBXTokenizer.h" +#include "FBXParser.h" +#include "FBXDocument.h" +#include "FBXDocumentUtil.h" +#include "FBXProperties.h" + +namespace Assimp { +namespace FBX { + + using namespace Util; + +// ------------------------------------------------------------------------------------------------ +Property::Property() +{ +} + +// ------------------------------------------------------------------------------------------------ +Property::~Property() +{ +} + +namespace { + +// ------------------------------------------------------------------------------------------------ +// read a typed property out of a FBX element. The return value is NULL if the property cannot be read. +Property* ReadTypedProperty(const Element& element) +{ + ai_assert(element.KeyToken().StringContents() == "P"); + + const TokenList& tok = element.Tokens(); + ai_assert(tok.size() >= 5); + + const std::string& s = ParseTokenAsString(*tok[1]); + const char* const cs = s.c_str(); + if (!strcmp(cs,"KString")) { + return new TypedProperty<std::string>(ParseTokenAsString(*tok[4])); + } + else if (!strcmp(cs,"bool") || !strcmp(cs,"Bool")) { + return new TypedProperty<bool>(ParseTokenAsInt(*tok[4]) != 0); + } + else if (!strcmp(cs,"int") || !strcmp(cs,"enum")) { + return new TypedProperty<int>(ParseTokenAsInt(*tok[4])); + } + else if (!strcmp(cs,"ULongLong")) { + return new TypedProperty<uint64_t>(ParseTokenAsID(*tok[4])); + } + else if (!strcmp(cs,"Vector3D") || + !strcmp(cs,"ColorRGB") || + !strcmp(cs,"Vector") || + !strcmp(cs,"Color") || + !strcmp(cs,"Lcl Translation") || + !strcmp(cs,"Lcl Rotation") || + !strcmp(cs,"Lcl Scaling") + ) { + return new TypedProperty<aiVector3D>(aiVector3D( + ParseTokenAsFloat(*tok[4]), + ParseTokenAsFloat(*tok[5]), + ParseTokenAsFloat(*tok[6])) + ); + } + else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float")) { + return new TypedProperty<float>(ParseTokenAsFloat(*tok[4])); + } + return NULL; +} + + +// ------------------------------------------------------------------------------------------------ +// peek into an element and check if it contains a FBX property, if so return its name. +std::string PeekPropertyName(const Element& element) +{ + ai_assert(element.KeyToken().StringContents() == "P"); + const TokenList& tok = element.Tokens(); + if(tok.size() < 4) { + return ""; + } + + return ParseTokenAsString(*tok[0]); +} + +} //! anon + + +// ------------------------------------------------------------------------------------------------ +PropertyTable::PropertyTable() +: templateProps() +, element() +{ +} + + +// ------------------------------------------------------------------------------------------------ +PropertyTable::PropertyTable(const Element& element, boost::shared_ptr<const PropertyTable> templateProps) +: templateProps(templateProps) +, element(&element) +{ + const Scope& scope = GetRequiredScope(element); + BOOST_FOREACH(const ElementMap::value_type& v, scope.Elements()) { + if(v.first != "P") { + DOMWarning("expected only P elements in property table",v.second); + continue; + } + + const std::string& name = PeekPropertyName(*v.second); + if(!name.length()) { + DOMWarning("could not read property name",v.second); + continue; + } + + LazyPropertyMap::const_iterator it = lazyProps.find(name); + if (it != lazyProps.end()) { + DOMWarning("duplicate property name, will hide previous value: " + name,v.second); + continue; + } + + lazyProps[name] = v.second; + } +} + + +// ------------------------------------------------------------------------------------------------ +PropertyTable::~PropertyTable() +{ + BOOST_FOREACH(PropertyMap::value_type& v, props) { + delete v.second; + } +} + + +// ------------------------------------------------------------------------------------------------ +const Property* PropertyTable::Get(const std::string& name) const +{ + PropertyMap::const_iterator it = props.find(name); + if (it == props.end()) { + // hasn't been parsed yet? + LazyPropertyMap::const_iterator lit = lazyProps.find(name); + if(lit != lazyProps.end()) { + props[name] = ReadTypedProperty(*(*lit).second); + it = props.find(name); + + ai_assert(it != props.end()); + } + + if (it == props.end()) { + // check property template + if(templateProps) { + return templateProps->Get(name); + } + + return NULL; + } + } + + return (*it).second; +} + +DirectPropertyMap PropertyTable::GetUnparsedProperties() const +{ + DirectPropertyMap result; + + // Loop through all the lazy properties (which is all the properties) + BOOST_FOREACH(const LazyPropertyMap::value_type& element, lazyProps) { + + // Skip parsed properties + if (props.end() != props.find(element.first)) continue; + + // Read the element's value. + // Wrap the naked pointer (since the call site is required to acquire ownership) + // std::unique_ptr from C++11 would be preferred both as a wrapper and a return value. + boost::shared_ptr<Property> prop = boost::shared_ptr<Property>(ReadTypedProperty(*element.second)); + + // Element could not be read. Skip it. + if (!prop) continue; + + // Add to result + result[element.first] = prop; + } + + return result; +} + + + +} //! FBX +} //! Assimp + +#endif diff --git a/src/3rdparty/assimp/code/FBXProperties.h b/src/3rdparty/assimp/code/FBXProperties.h new file mode 100644 index 000000000..9219c3eea --- /dev/null +++ b/src/3rdparty/assimp/code/FBXProperties.h @@ -0,0 +1,191 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXProperties.h + * @brief FBX dynamic properties + */ +#ifndef INCLUDED_AI_FBX_PROPERTIES_H +#define INCLUDED_AI_FBX_PROPERTIES_H + +#include <map> +#include <string> + +namespace Assimp { +namespace FBX { + + class Element; + + +/** Represents a dynamic property. Type info added by deriving classes, + * see #TypedProperty. + Example: + @verbatim + P: "ShininessExponent", "double", "Number", "",0.5 + @endvebatim + +*/ +class Property +{ +protected: + + Property(); + +public: + + virtual ~Property(); + +public: + + template <typename T> + const T* As() const { + return dynamic_cast<const T*>(this); + } +}; + + +template<typename T> +class TypedProperty : public Property +{ +public: + + TypedProperty(const T& value) + : value(value) + { + } + +public: + + const T& Value() const { + return value; + } + +private: + T value; +}; + + +typedef std::fbx_unordered_map<std::string,boost::shared_ptr<Property> > DirectPropertyMap; +typedef std::fbx_unordered_map<std::string,const Property*> PropertyMap; +typedef std::fbx_unordered_map<std::string,const Element*> LazyPropertyMap; + +/** Represents a property table as can be found in the newer FBX files (Properties60, Properties70)*/ +class PropertyTable +{ +public: + + // in-memory property table with no source element + PropertyTable(); + + PropertyTable(const Element& element, boost::shared_ptr<const PropertyTable> templateProps); + ~PropertyTable(); + +public: + + const Property* Get(const std::string& name) const; + + // PropertyTable's need not be coupled with FBX elements so this can be NULL + const Element* GetElement() const { + return element; + } + + const PropertyTable* TemplateProps() const { + return templateProps.get(); + } + + DirectPropertyMap GetUnparsedProperties() const; + +private: + + LazyPropertyMap lazyProps; + mutable PropertyMap props; + const boost::shared_ptr<const PropertyTable> templateProps; + const Element* const element; +}; + + +// ------------------------------------------------------------------------------------------------ +template <typename T> +inline T PropertyGet(const PropertyTable& in, const std::string& name, + const T& defaultValue, + bool ignoreTemplate = false) +{ + const Property* const prop = in.Get(name); + if(!prop) { + return defaultValue; + } + + // strong typing, no need to be lenient + const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >(); + if(!tprop) { + return defaultValue; + } + + return tprop->Value(); +} + + +// ------------------------------------------------------------------------------------------------ +template <typename T> +inline T PropertyGet(const PropertyTable& in, const std::string& name, + bool& result, + bool ignoreTemplate = false) +{ + const Property* const prop = in.Get(name); + if(!prop) { + result = false; + return T(); + } + + // strong typing, no need to be lenient + const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >(); + if(!tprop) { + result = false; + return T(); + } + + result = true; + return tprop->Value(); +} + + +} //! FBX +} //! Assimp + +#endif // diff --git a/src/3rdparty/assimp/code/FBXTokenizer.cpp b/src/3rdparty/assimp/code/FBXTokenizer.cpp new file mode 100644 index 000000000..7aa81543a --- /dev/null +++ b/src/3rdparty/assimp/code/FBXTokenizer.cpp @@ -0,0 +1,246 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXTokenizer.cpp + * @brief Implementation of the FBX broadphase lexer + */ +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +// tab width for logging columns +#define ASSIMP_FBX_TAB_WIDTH 4 + +#include "ParsingUtils.h" + +#include "FBXTokenizer.h" +#include "FBXUtil.h" + +namespace Assimp { +namespace FBX { + +// ------------------------------------------------------------------------------------------------ +Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column) + : sbegin(sbegin) + , send(send) + , type(type) + , line(line) + , column(column) +#ifdef DEBUG + , contents(sbegin, static_cast<size_t>(send-sbegin)) +#endif +{ + ai_assert(sbegin); + ai_assert(send); + + // tokens must be of non-zero length + ai_assert(static_cast<size_t>(send-sbegin) > 0); +} + + +// ------------------------------------------------------------------------------------------------ +Token::~Token() +{ +} + + +namespace { + +// ------------------------------------------------------------------------------------------------ +// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError. +void TokenizeError(const std::string& message, unsigned int line, unsigned int column) +{ + throw DeadlyImportError(Util::AddLineAndColumn("FBX-Tokenize",message,line,column)); +} + + +// process a potential data token up to 'cur', adding it to 'output_tokens'. +// ------------------------------------------------------------------------------------------------ +void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*& end, + unsigned int line, + unsigned int column, + TokenType type = TokenType_DATA, + bool must_have_token = false) +{ + if (start && end) { + // sanity check: + // tokens should have no whitespace outside quoted text and [start,end] should + // properly delimit the valid range. + bool in_double_quotes = false; + for (const char* c = start; c != end + 1; ++c) { + if (*c == '\"') { + in_double_quotes = !in_double_quotes; + } + + if (!in_double_quotes && IsSpaceOrNewLine(*c)) { + TokenizeError("unexpected whitespace in token", line, column); + } + } + + if (in_double_quotes) { + TokenizeError("non-terminated double quotes", line, column); + } + + output_tokens.push_back(new_Token(start,end + 1,type,line,column)); + } + else if (must_have_token) { + TokenizeError("unexpected character, expected data token", line, column); + } + + start = end = NULL; +} + +} + +// ------------------------------------------------------------------------------------------------ +void Tokenize(TokenList& output_tokens, const char* input) +{ + ai_assert(input); + + // line and column numbers numbers are one-based + unsigned int line = 1; + unsigned int column = 1; + + bool comment = false; + bool in_double_quotes = false; + bool pending_data_token = false; + + const char* token_begin = NULL, *token_end = NULL; + for (const char* cur = input;*cur;column += (*cur == '\t' ? ASSIMP_FBX_TAB_WIDTH : 1), ++cur) { + const char c = *cur; + + if (IsLineEnd(c)) { + comment = false; + + column = 0; + ++line; + } + + if(comment) { + continue; + } + + if(in_double_quotes) { + if (c == '\"') { + in_double_quotes = false; + token_end = cur; + + ProcessDataToken(output_tokens,token_begin,token_end,line,column); + pending_data_token = false; + } + continue; + } + + switch(c) + { + case '\"': + if (token_begin) { + TokenizeError("unexpected double-quote", line, column); + } + token_begin = cur; + in_double_quotes = true; + continue; + + case ';': + ProcessDataToken(output_tokens,token_begin,token_end,line,column); + comment = true; + continue; + + case '{': + ProcessDataToken(output_tokens,token_begin,token_end, line, column); + output_tokens.push_back(new_Token(cur,cur+1,TokenType_OPEN_BRACKET,line,column)); + continue; + + case '}': + ProcessDataToken(output_tokens,token_begin,token_end,line,column); + output_tokens.push_back(new_Token(cur,cur+1,TokenType_CLOSE_BRACKET,line,column)); + continue; + + case ',': + if (pending_data_token) { + ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_DATA,true); + } + output_tokens.push_back(new_Token(cur,cur+1,TokenType_COMMA,line,column)); + continue; + + case ':': + if (pending_data_token) { + ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_KEY,true); + } + else { + TokenizeError("unexpected colon", line, column); + } + continue; + } + + if (IsSpaceOrNewLine(c)) { + + if (token_begin) { + // peek ahead and check if the next token is a colon in which + // case this counts as KEY token. + TokenType type = TokenType_DATA; + for (const char* peek = cur; *peek && IsSpaceOrNewLine(*peek); ++peek) { + if (*peek == ':') { + type = TokenType_KEY; + cur = peek; + break; + } + } + + ProcessDataToken(output_tokens,token_begin,token_end,line,column,type); + } + + pending_data_token = false; + } + else { + token_end = cur; + if (!token_begin) { + token_begin = cur; + } + + pending_data_token = true; + } + } +} + +} // !FBX +} // !Assimp + +#endif diff --git a/src/3rdparty/assimp/code/FBXTokenizer.h b/src/3rdparty/assimp/code/FBXTokenizer.h new file mode 100644 index 000000000..0a4339a50 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXTokenizer.h @@ -0,0 +1,190 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXTokenizer.h + * @brief FBX lexer + */ +#ifndef INCLUDED_AI_FBX_TOKENIZER_H +#define INCLUDED_AI_FBX_TOKENIZER_H + +#include <boost/shared_ptr.hpp> + +#include "FBXCompileConfig.h" + +namespace Assimp { +namespace FBX { + +/** Rough classification for text FBX tokens used for constructing the + * basic scope hierarchy. */ +enum TokenType +{ + // { + TokenType_OPEN_BRACKET = 0, + + // } + TokenType_CLOSE_BRACKET, + + // '"blablubb"', '2', '*14' - very general token class, + // further processing happens at a later stage. + TokenType_DATA, + + // + TokenType_BINARY_DATA, + + // , + TokenType_COMMA, + + // blubb: + TokenType_KEY +}; + + +/** Represents a single token in a FBX file. Tokens are + * classified by the #TokenType enumerated types. + * + * Offers iterator protocol. Tokens are immutable. */ +class Token +{ + +private: + + static const unsigned int BINARY_MARKER = static_cast<unsigned int>(-1); + +public: + + /** construct a textual token */ + Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column); + + /** construct a binary token */ + Token(const char* sbegin, const char* send, TokenType type, unsigned int offset); + + ~Token(); + +public: + + std::string StringContents() const { + return std::string(begin(),end()); + } + +public: + + bool IsBinary() const { + return column == BINARY_MARKER; + } + + const char* begin() const { + return sbegin; + } + + const char* end() const { + return send; + } + + TokenType Type() const { + return type; + } + + unsigned int Offset() const { + ai_assert(IsBinary()); + return offset; + } + + unsigned int Line() const { + ai_assert(!IsBinary()); + return line; + } + + unsigned int Column() const { + ai_assert(!IsBinary()); + return column; + } + +private: + +#ifdef DEBUG + // full string copy for the sole purpose that it nicely appears + // in msvc's debugger window. + const std::string contents; +#endif + + + const char* const sbegin; + const char* const send; + const TokenType type; + + union { + const unsigned int line; + unsigned int offset; + }; + const unsigned int column; +}; + +// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03 +typedef const Token* TokenPtr; +typedef std::vector< TokenPtr > TokenList; + +#define new_Token new Token + + +/** Main FBX tokenizer function. Transform input buffer into a list of preprocessed tokens. + * + * Skips over comments and generates line and column numbers. + * + * @param output_tokens Receives a list of all tokens in the input data. + * @param input_buffer Textual input buffer to be processed, 0-terminated. + * @throw DeadlyImportError if something goes wrong */ +void Tokenize(TokenList& output_tokens, const char* input); + + +/** Tokenizer function for binary FBX files. + * + * Emits a token list suitable for direct parsing. + * + * @param output_tokens Receives a list of all tokens in the input data. + * @param input_buffer Binary input buffer to be processed. + * @param length Length of input buffer, in bytes. There is no 0-terminal. + * @throw DeadlyImportError if something goes wrong */ +void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length); + + +} // ! FBX +} // ! Assimp + +#endif // ! INCLUDED_AI_FBX_PARSER_H diff --git a/src/3rdparty/assimp/code/FBXUtil.cpp b/src/3rdparty/assimp/code/FBXUtil.cpp new file mode 100644 index 000000000..aaf311d03 --- /dev/null +++ b/src/3rdparty/assimp/code/FBXUtil.cpp @@ -0,0 +1,119 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXUtil.cpp + * @brief Implementation of internal FBX utility functions + */ +#include "AssimpPCH.h" + +#include "FBXUtil.h" +#include "FBXTokenizer.h" + +#include "TinyFormatter.h" + +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER + +namespace Assimp { +namespace FBX { +namespace Util { + +// ------------------------------------------------------------------------------------------------ +const char* TokenTypeString(TokenType t) +{ + switch(t) { + case TokenType_OPEN_BRACKET: + return "TOK_OPEN_BRACKET"; + + case TokenType_CLOSE_BRACKET: + return "TOK_CLOSE_BRACKET"; + + case TokenType_DATA: + return "TOK_DATA"; + + case TokenType_COMMA: + return "TOK_COMMA"; + + case TokenType_KEY: + return "TOK_KEY"; + + case TokenType_BINARY_DATA: + return "TOK_BINARY_DATA"; + } + + ai_assert(false); + return ""; +} + + +// ------------------------------------------------------------------------------------------------ +std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset) +{ + return static_cast<std::string>( (Formatter::format(),prefix," (offset 0x",std::hex,offset,") ",text) ); +} + +// ------------------------------------------------------------------------------------------------ +std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column) +{ + return static_cast<std::string>( (Formatter::format(),prefix," (line ",line,", col ",column,") ",text) ); +} + +// ------------------------------------------------------------------------------------------------ +std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok) +{ + if(tok->IsBinary()) { + return static_cast<std::string>( (Formatter::format(),prefix, + " (",TokenTypeString(tok->Type()), + ", offset 0x", std::hex, tok->Offset(),") ", + text) ); + } + + return static_cast<std::string>( (Formatter::format(),prefix, + " (",TokenTypeString(tok->Type()), + ", line ",tok->Line(), + ", col ",tok->Column(),") ", + text) ); +} + +} // !Util +} // !FBX +} // !Assimp + +#endif + diff --git a/src/3rdparty/assimp/code/FBXUtil.h b/src/3rdparty/assimp/code/FBXUtil.h new file mode 100644 index 000000000..a205b598d --- /dev/null +++ b/src/3rdparty/assimp/code/FBXUtil.h @@ -0,0 +1,104 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file FBXUtil.h + * @brief FBX utility functions for internal use + */ +#ifndef INCLUDED_AI_FBX_UTIL_H +#define INCLUDED_AI_FBX_UTIL_H + +#include <string> +#include "FBXCompileConfig.h" +#include "FBXTokenizer.h" + +namespace Assimp { +namespace FBX { + + +namespace Util { + + +/** helper for std::for_each to delete all heap-allocated items in a container */ +template<typename T> +struct delete_fun +{ + void operator()(const volatile T* del) { + delete del; + } +}; + +/** Get a string representation for a #TokenType. */ +const char* TokenTypeString(TokenType t); + + + +/** Format log/error messages using a given offset in the source binary file + * + * @param prefix Message prefix to be preprended to the location info. + * @param text Message text + * @param line Line index, 1-based + * @param column Colum index, 1-based + * @return A string of the following format: {prefix} (offset 0x{offset}) {text}*/ +std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset); + + +/** Format log/error messages using a given line location in the source file. + * + * @param prefix Message prefix to be preprended to the location info. + * @param text Message text + * @param line Line index, 1-based + * @param column Colum index, 1-based + * @return A string of the following format: {prefix} (line {line}, col {column}) {text}*/ +std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column); + + +/** Format log/error messages using a given cursor token. + * + * @param prefix Message prefix to be preprended to the location info. + * @param text Message text + * @param tok Token where parsing/processing stopped + * @return A string of the following format: {prefix} ({token-type}, line {line}, col {column}) {text}*/ +std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok); + +} +} +} + +#endif // ! INCLUDED_AI_FBX_UTIL_H diff --git a/src/3rdparty/assimp/code/FindDegenerates.h b/src/3rdparty/assimp/code/FindDegenerates.h index ec82882d4..35703a49b 100644 --- a/src/3rdparty/assimp/code/FindDegenerates.h +++ b/src/3rdparty/assimp/code/FindDegenerates.h @@ -53,7 +53,7 @@ namespace Assimp { // --------------------------------------------------------------------------- /** FindDegeneratesProcess: Searches a mesh for degenerated triangles. */ -class FindDegeneratesProcess : public BaseProcess +class ASSIMP_API FindDegeneratesProcess : public BaseProcess { public: diff --git a/src/3rdparty/assimp/code/FindInvalidDataProcess.h b/src/3rdparty/assimp/code/FindInvalidDataProcess.h index fa6922f29..6d3c812fe 100644 --- a/src/3rdparty/assimp/code/FindInvalidDataProcess.h +++ b/src/3rdparty/assimp/code/FindInvalidDataProcess.h @@ -51,13 +51,12 @@ class FindInvalidDataProcessTest; namespace Assimp { // --------------------------------------------------------------------------- -/** The FindInvalidData postprocessing step. It searches the mesh data +/** The FindInvalidData post-processing step. It searches the mesh data * for parts that are obviously invalid and removes them. * * Originally this was a workaround for some models written by Blender * which have zero normal vectors. */ -class FindInvalidDataProcess - : public BaseProcess +class ASSIMP_API FindInvalidDataProcess : public BaseProcess { public: diff --git a/src/3rdparty/assimp/code/GenVertexNormalsProcess.cpp b/src/3rdparty/assimp/code/GenVertexNormalsProcess.cpp index 8c977cce6..e4f96b6e8 100644 --- a/src/3rdparty/assimp/code/GenVertexNormalsProcess.cpp +++ b/src/3rdparty/assimp/code/GenVertexNormalsProcess.cpp @@ -142,7 +142,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]]; - const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize(); + const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)); for (unsigned int i = 0;i < face.mNumIndices;++i) { pMesh->mNormals[face.mIndices[i]] = vNor; @@ -209,18 +209,19 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int // Get all vertices that share this one ... vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound); + aiVector3D vr = pMesh->mNormals[i]; + float vrlen = vr.Length(); + aiVector3D pcNor; for (unsigned int a = 0; a < verticesFound.size(); ++a) { - const aiVector3D& v = pMesh->mNormals[verticesFound[a]]; + aiVector3D v = pMesh->mNormals[verticesFound[a]]; // check whether the angle between the two normals is not too large // HACK: if v.x is qnan the dot product will become qnan, too // therefore the comparison against fLimit should be false // in every case. - if (v * pMesh->mNormals[i] < fLimit) - continue; - - pcNor += v; + if (v * vr >= fLimit * vrlen * v.Length()) + pcNor += v; } pcNew[i] = pcNor.Normalize(); } diff --git a/src/3rdparty/assimp/code/IFCBoolean.cpp b/src/3rdparty/assimp/code/IFCBoolean.cpp new file mode 100644 index 000000000..8573e4d62 --- /dev/null +++ b/src/3rdparty/assimp/code/IFCBoolean.cpp @@ -0,0 +1,729 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2010, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file IFCBoolean.cpp + * @brief Implements a subset of Ifc boolean operations + */ + +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER +#include "IFCUtil.h" +#include "PolyTools.h" +#include "ProcessHelper.h" + +#include <iterator> + +namespace Assimp { + namespace IFC { + +// ------------------------------------------------------------------------------------------------ +enum Intersect { + Intersect_No, + Intersect_LiesOnPlane, + Intersect_Yes +}; + +// ------------------------------------------------------------------------------------------------ +Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const IfcVector3& e0, + const IfcVector3& e1, + IfcVector3& out) +{ + const IfcVector3 pdelta = e0 - p, seg = e1-e0; + const IfcFloat dotOne = n*seg, dotTwo = -(n*pdelta); + + if (fabs(dotOne) < 1e-6) { + return fabs(dotTwo) < 1e-6f ? Intersect_LiesOnPlane : Intersect_No; + } + + const IfcFloat t = dotTwo/dotOne; + // t must be in [0..1] if the intersection point is within the given segment + if (t > 1.f || t < 0.f) { + return Intersect_No; + } + out = e0+t*seg; + return Intersect_Yes; +} + +// ------------------------------------------------------------------------------------------------ +void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result, + const TempMesh& first_operand, + ConversionData& conv) +{ + ai_assert(hs != NULL); + + const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>(); + if(!plane) { + IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid"); + return; + } + + // extract plane base position vector and normal vector + IfcVector3 p,n(0.f,0.f,1.f); + if (plane->Position->Axis) { + ConvertDirection(n,plane->Position->Axis.Get()); + } + ConvertCartesianPoint(p,plane->Position->Location); + + if(!IsTrue(hs->AgreementFlag)) { + n *= -1.f; + } + + // clip the current contents of `meshout` against the plane we obtained from the second operand + const std::vector<IfcVector3>& in = first_operand.verts; + std::vector<IfcVector3>& outvert = result.verts; + + std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin(), + end = first_operand.vertcnt.end(), iit; + + outvert.reserve(in.size()); + result.vertcnt.reserve(first_operand.vertcnt.size()); + + unsigned int vidx = 0; + for(iit = begin; iit != end; vidx += *iit++) { + + unsigned int newcount = 0; + for(unsigned int i = 0; i < *iit; ++i) { + const IfcVector3& e0 = in[vidx+i], e1 = in[vidx+(i+1)%*iit]; + + // does the next segment intersect the plane? + IfcVector3 isectpos; + const Intersect isect = IntersectSegmentPlane(p,n,e0,e1,isectpos); + if (isect == Intersect_No || isect == Intersect_LiesOnPlane) { + if ( (e0-p).Normalize()*n > 0 ) { + outvert.push_back(e0); + ++newcount; + } + } + else if (isect == Intersect_Yes) { + if ( (e0-p).Normalize()*n > 0 ) { + // e0 is on the right side, so keep it + outvert.push_back(e0); + outvert.push_back(isectpos); + newcount += 2; + } + else { + // e0 is on the wrong side, so drop it and keep e1 instead + outvert.push_back(isectpos); + ++newcount; + } + } + } + + if (!newcount) { + continue; + } + + IfcVector3 vmin,vmax; + ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax); + + // filter our IfcFloat points - those may happen if a point lies + // directly on the intersection line. However, due to IfcFloat + // precision a bitwise comparison is not feasible to detect + // this case. + const IfcFloat epsilon = (vmax-vmin).SquareLength() / 1e6f; + FuzzyVectorCompare fz(epsilon); + + std::vector<IfcVector3>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz ); + + if (e != outvert.end()) { + newcount -= static_cast<unsigned int>(std::distance(e,outvert.end())); + outvert.erase(e,outvert.end()); + } + if (fz(*( outvert.end()-newcount),outvert.back())) { + outvert.pop_back(); + --newcount; + } + if(newcount > 2) { + result.vertcnt.push_back(newcount); + } + else while(newcount-->0) { + result.verts.pop_back(); + } + + } + IFCImporter::LogDebug("generating CSG geometry by plane clipping (IfcBooleanClippingResult)"); +} + +// ------------------------------------------------------------------------------------------------ +// Check if e0-e1 intersects a sub-segment of the given boundary line. +// note: this functions works on 3D vectors, but performs its intersection checks solely in xy. +bool IntersectsBoundaryProfile( const IfcVector3& e0, const IfcVector3& e1, const std::vector<IfcVector3>& boundary, + std::vector<size_t>& intersected_boundary_segments, + std::vector<IfcVector3>& intersected_boundary_points, + bool half_open = false, + bool* e0_hits_border = NULL) +{ + ai_assert(intersected_boundary_segments.empty()); + ai_assert(intersected_boundary_points.empty()); + + if(e0_hits_border) { + *e0_hits_border = false; + } + + const IfcVector3& e = e1 - e0; + + for (size_t i = 0, bcount = boundary.size(); i < bcount; ++i) { + // boundary segment i: b0-b1 + const IfcVector3& b0 = boundary[i]; + const IfcVector3& b1 = boundary[(i+1) % bcount]; + + const IfcVector3& b = b1 - b0; + + // segment-segment intersection + // solve b0 + b*s = e0 + e*t for (s,t) + const IfcFloat det = (-b.x * e.y + e.x * b.y); + if(fabs(det) < 1e-6) { + // no solutions (parallel lines) + continue; + } + + const IfcFloat x = b0.x - e0.x; + const IfcFloat y = b0.y - e0.y; + + const IfcFloat s = (x*e.y - e.x*y)/det; + const IfcFloat t = (x*b.y - b.x*y)/det; + +#ifdef ASSIMP_BUILD_DEBUG + const IfcVector3 check = b0 + b*s - (e0 + e*t); + ai_assert((IfcVector2(check.x,check.y)).SquareLength() < 1e-5); +#endif + + // for a valid intersection, s-t should be in range [0,1]. + // note that for t (i.e. the segment point) we only use a + // half-sided epsilon because the next segment should catch + // this case. + const IfcFloat epsilon = 1e-6; + if (t >= -epsilon && (t <= 1.0+epsilon || half_open) && s >= -epsilon && s <= 1.0) { + + if (e0_hits_border && !*e0_hits_border) { + *e0_hits_border = fabs(t) < 1e-5f; + } + + const IfcVector3& p = e0 + e*t; + + // only insert the point into the list if it is sufficiently + // far away from the previous intersection point. This way, + // we avoid duplicate detection if the intersection is + // directly on the vertex between two segments. + if (!intersected_boundary_points.empty() && intersected_boundary_segments.back()==i-1 ) { + const IfcVector3 diff = intersected_boundary_points.back() - p; + if(IfcVector2(diff.x, diff.y).SquareLength() < 1e-7) { + continue; + } + } + intersected_boundary_segments.push_back(i); + intersected_boundary_points.push_back(p); + } + } + + return !intersected_boundary_segments.empty(); +} + + +// ------------------------------------------------------------------------------------------------ +// note: this functions works on 3D vectors, but performs its intersection checks solely in xy. +bool PointInPoly(const IfcVector3& p, const std::vector<IfcVector3>& boundary) +{ + // even-odd algorithm: take a random vector that extends from p to infinite + // and counts how many times it intersects edges of the boundary. + // because checking for segment intersections is prone to numeric inaccuracies + // or double detections (i.e. when hitting multiple adjacent segments at their + // shared vertices) we do it thrice with different rays and vote on it. + + // the even-odd algorithm doesn't work for points which lie directly on + // the border of the polygon. If any of our attempts produces this result, + // we return false immediately. + + std::vector<size_t> intersected_boundary_segments; + std::vector<IfcVector3> intersected_boundary_points; + size_t votes = 0; + + bool is_border; + IntersectsBoundaryProfile(p, p + IfcVector3(1.0,0,0), boundary, + intersected_boundary_segments, + intersected_boundary_points, true, &is_border); + + if(is_border) { + return false; + } + + votes += intersected_boundary_segments.size() % 2; + + intersected_boundary_segments.clear(); + intersected_boundary_points.clear(); + + IntersectsBoundaryProfile(p, p + IfcVector3(0,1.0,0), boundary, + intersected_boundary_segments, + intersected_boundary_points, true, &is_border); + + if(is_border) { + return false; + } + + votes += intersected_boundary_segments.size() % 2; + + intersected_boundary_segments.clear(); + intersected_boundary_points.clear(); + + IntersectsBoundaryProfile(p, p + IfcVector3(0.6,-0.6,0.0), boundary, + intersected_boundary_segments, + intersected_boundary_points, true, &is_border); + + if(is_border) { + return false; + } + + votes += intersected_boundary_segments.size() % 2; + //ai_assert(votes == 3 || votes == 0); + return votes > 1; +} + + +// ------------------------------------------------------------------------------------------------ +void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, + const TempMesh& first_operand, + ConversionData& conv) +{ + ai_assert(hs != NULL); + + const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>(); + if(!plane) { + IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid"); + return; + } + + // extract plane base position vector and normal vector + IfcVector3 p,n(0.f,0.f,1.f); + if (plane->Position->Axis) { + ConvertDirection(n,plane->Position->Axis.Get()); + } + ConvertCartesianPoint(p,plane->Position->Location); + + if(!IsTrue(hs->AgreementFlag)) { + n *= -1.f; + } + + n.Normalize(); + + // obtain the polygonal bounding volume + boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh()); + if(!ProcessCurve(hs->PolygonalBoundary, *profile.get(), conv)) { + IFCImporter::LogError("expected valid polyline for boundary of boolean halfspace"); + return; + } + + IfcMatrix4 proj_inv; + ConvertAxisPlacement(proj_inv,hs->Position); + + // and map everything into a plane coordinate space so all intersection + // tests can be done in 2D space. + IfcMatrix4 proj = proj_inv; + proj.Inverse(); + + // clip the current contents of `meshout` against the plane we obtained from the second operand + const std::vector<IfcVector3>& in = first_operand.verts; + std::vector<IfcVector3>& outvert = result.verts; + + std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin(), + end = first_operand.vertcnt.end(), iit; + + outvert.reserve(in.size()); + result.vertcnt.reserve(first_operand.vertcnt.size()); + + std::vector<size_t> intersected_boundary_segments; + std::vector<IfcVector3> intersected_boundary_points; + + // TODO: the following algorithm doesn't handle all cases. + unsigned int vidx = 0; + for(iit = begin; iit != end; vidx += *iit++) { + if (!*iit) { + continue; + } + + unsigned int newcount = 0; + bool was_outside_boundary = !PointInPoly(proj * in[vidx], profile->verts); + + // used any more? + //size_t last_intersected_boundary_segment; + IfcVector3 last_intersected_boundary_point; + + bool extra_point_flag = false; + IfcVector3 extra_point; + + IfcVector3 enter_volume; + bool entered_volume_flag = false; + + for(unsigned int i = 0; i < *iit; ++i) { + // current segment: [i,i+1 mod size] or [*extra_point,i] if extra_point_flag is set + const IfcVector3& e0 = extra_point_flag ? extra_point : in[vidx+i]; + const IfcVector3& e1 = extra_point_flag ? in[vidx+i] : in[vidx+(i+1)%*iit]; + + // does the current segment intersect the polygonal boundary? + const IfcVector3& e0_plane = proj * e0; + const IfcVector3& e1_plane = proj * e1; + + intersected_boundary_segments.clear(); + intersected_boundary_points.clear(); + + const bool is_outside_boundary = !PointInPoly(e1_plane, profile->verts); + const bool is_boundary_intersection = is_outside_boundary != was_outside_boundary; + + IntersectsBoundaryProfile(e0_plane, e1_plane, profile->verts, + intersected_boundary_segments, + intersected_boundary_points); + + ai_assert(!is_boundary_intersection || !intersected_boundary_segments.empty()); + + // does the current segment intersect the plane? + // (no extra check if this is an extra point) + IfcVector3 isectpos; + const Intersect isect = extra_point_flag ? Intersect_No : IntersectSegmentPlane(p,n,e0,e1,isectpos); + +#ifdef ASSIMP_BUILD_DEBUG + if (isect == Intersect_Yes) { + const IfcFloat f = fabs((isectpos - p)*n); + ai_assert(f < 1e-5); + } +#endif + + const bool is_white_side = (e0-p)*n >= -1e-6; + + // e0 on good side of plane? (i.e. we should keep all geometry on this side) + if (is_white_side) { + // but is there an intersection in e0-e1 and is e1 in the clipping + // boundary? In this case, generate a line that only goes to the + // intersection point. + if (isect == Intersect_Yes && !is_outside_boundary) { + outvert.push_back(e0); + ++newcount; + + outvert.push_back(isectpos); + ++newcount; + + /* + // this is, however, only a line that goes to the plane, but not + // necessarily to the point where the bounding volume on the + // black side of the plane is hit. So basically, we need another + // check for [isectpos-e1], which should yield an intersection + // point. + extra_point_flag = true; + extra_point = isectpos; + + was_outside_boundary = true; + continue; */ + + // [isectpos, enter_volume] potentially needs extra points. + // For this, we determine the intersection point with the + // bounding volume and project it onto the plane. + /* + const IfcVector3& enter_volume_proj = proj * enter_volume; + const IfcVector3& enter_isectpos = proj * isectpos; + + intersected_boundary_segments.clear(); + intersected_boundary_points.clear(); + + IntersectsBoundaryProfile(enter_volume_proj, enter_isectpos, profile->verts, + intersected_boundary_segments, + intersected_boundary_points); + + if(!intersected_boundary_segments.empty()) { + + vec = vec + ((p - vec) * n) * n; + } + */ + + //entered_volume_flag = true; + } + else { + outvert.push_back(e0); + ++newcount; + } + } + // e0 on bad side of plane, e1 on good (i.e. we should remove geometry on this side, + // but only if it is within the bounding volume). + else if (isect == Intersect_Yes) { + // is e0 within the clipping volume? Insert the intersection point + // of [e0,e1] and the plane instead of e0. + if(was_outside_boundary) { + outvert.push_back(e0); + } + else { + if(entered_volume_flag) { + const IfcVector3& fix_point = enter_volume + ((p - enter_volume) * n) * n; + outvert.push_back(fix_point); + ++newcount; + } + + outvert.push_back(isectpos); + } + entered_volume_flag = false; + ++newcount; + } + else { // no intersection with plane or parallel; e0,e1 are on the bad side + + // did we just pass the boundary line to the poly bounding? + if (is_boundary_intersection) { + + // and are now outside the clipping boundary? + if (is_outside_boundary) { + // in this case, get the point where the clipping boundary + // was entered first. Then, get the point where the clipping + // boundary volume was left! These two points with the plane + // normal form another plane that intersects the clipping + // volume. There are two ways to get from the first to the + // second point along the intersection curve, try to pick the + // one that lies within the current polygon. + + // TODO this approach doesn't handle all cases + + // ... + + IfcFloat d = 1e20; + IfcVector3 vclosest; + BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) { + const IfcFloat dn = (v-e1_plane).SquareLength(); + if (dn < d) { + d = dn; + vclosest = v; + } + } + + vclosest = proj_inv * vclosest; + if(entered_volume_flag) { + const IfcVector3& fix_point = vclosest + ((p - vclosest) * n) * n; + outvert.push_back(fix_point); + ++newcount; + + entered_volume_flag = false; + } + + outvert.push_back(vclosest); + ++newcount; + + //outvert.push_back(e1); + //++newcount; + } + else { + entered_volume_flag = true; + + // we just entered the clipping boundary. Record the point + // and the segment where we entered and also generate this point. + //last_intersected_boundary_segment = intersected_boundary_segments.front(); + //last_intersected_boundary_point = intersected_boundary_points.front(); + + outvert.push_back(e0); + ++newcount; + + IfcFloat d = 1e20; + IfcVector3 vclosest; + BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) { + const IfcFloat dn = (v-e0_plane).SquareLength(); + if (dn < d) { + d = dn; + vclosest = v; + } + } + + enter_volume = proj_inv * vclosest; + outvert.push_back(enter_volume); + ++newcount; + } + } + // if not, we just keep the vertex + else if (is_outside_boundary) { + outvert.push_back(e0); + ++newcount; + + entered_volume_flag = false; + } + } + + was_outside_boundary = is_outside_boundary; + extra_point_flag = false; + } + + if (!newcount) { + continue; + } + + IfcVector3 vmin,vmax; + ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax); + + // filter our IfcFloat points - those may happen if a point lies + // directly on the intersection line. However, due to IfcFloat + // precision a bitwise comparison is not feasible to detect + // this case. + const IfcFloat epsilon = (vmax-vmin).SquareLength() / 1e6f; + FuzzyVectorCompare fz(epsilon); + + std::vector<IfcVector3>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz ); + + if (e != outvert.end()) { + newcount -= static_cast<unsigned int>(std::distance(e,outvert.end())); + outvert.erase(e,outvert.end()); + } + if (fz(*( outvert.end()-newcount),outvert.back())) { + outvert.pop_back(); + --newcount; + } + if(newcount > 2) { + result.vertcnt.push_back(newcount); + } + else while(newcount-->0) { + result.verts.pop_back(); + } + + } + IFCImporter::LogDebug("generating CSG geometry by plane clipping with polygonal bounding (IfcBooleanClippingResult)"); +} + +// ------------------------------------------------------------------------------------------------ +void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result, + const TempMesh& first_operand, + ConversionData& conv) +{ + ai_assert(as != NULL); + + // This case is handled by reduction to an instance of the quadrify() algorithm. + // Obviously, this won't work for arbitrarily complex cases. In fact, the first + // operand should be near-planar. Luckily, this is usually the case in Ifc + // buildings. + + boost::shared_ptr<TempMesh> meshtmp = boost::shared_ptr<TempMesh>(new TempMesh()); + ProcessExtrudedAreaSolid(*as,*meshtmp,conv,false); + + std::vector<TempOpening> openings(1, TempOpening(as,IfcVector3(0,0,0),meshtmp,boost::shared_ptr<TempMesh>())); + + result = first_operand; + + TempMesh temp; + + std::vector<IfcVector3>::const_iterator vit = first_operand.verts.begin(); + BOOST_FOREACH(unsigned int pcount, first_operand.vertcnt) { + temp.Clear(); + + temp.verts.insert(temp.verts.end(), vit, vit + pcount); + temp.vertcnt.push_back(pcount); + + // The algorithms used to generate mesh geometry sometimes + // spit out lines or other degenerates which must be + // filtered to avoid running into assertions later on. + + // ComputePolygonNormal returns the Newell normal, so the + // length of the normal is the area of the polygon. + const IfcVector3& normal = temp.ComputeLastPolygonNormal(false); + if (normal.SquareLength() < static_cast<IfcFloat>(1e-5)) { + IFCImporter::LogWarn("skipping degenerate polygon (ProcessBooleanExtrudedAreaSolidDifference)"); + continue; + } + + GenerateOpenings(openings, std::vector<IfcVector3>(1,IfcVector3(1,0,0)), temp, false, true); + result.Append(temp); + + vit += pcount; + } + + IFCImporter::LogDebug("generating CSG geometry by geometric difference to a solid (IfcExtrudedAreaSolid)"); +} + +// ------------------------------------------------------------------------------------------------ +void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv) +{ + // supported CSG operations: + // DIFFERENCE + if(const IfcBooleanResult* const clip = boolean.ToPtr<IfcBooleanResult>()) { + if(clip->Operator != "DIFFERENCE") { + IFCImporter::LogWarn("encountered unsupported boolean operator: " + (std::string)clip->Operator); + return; + } + + // supported cases (1st operand): + // IfcBooleanResult -- call ProcessBoolean recursively + // IfcSweptAreaSolid -- obtain polygonal geometry first + + // supported cases (2nd operand): + // IfcHalfSpaceSolid -- easy, clip against plane + // IfcExtrudedAreaSolid -- reduce to an instance of the quadrify() algorithm + + + const IfcHalfSpaceSolid* const hs = clip->SecondOperand->ResolveSelectPtr<IfcHalfSpaceSolid>(conv.db); + const IfcExtrudedAreaSolid* const as = clip->SecondOperand->ResolveSelectPtr<IfcExtrudedAreaSolid>(conv.db); + if(!hs && !as) { + IFCImporter::LogError("expected IfcHalfSpaceSolid or IfcExtrudedAreaSolid as second clipping operand"); + return; + } + + TempMesh first_operand; + if(const IfcBooleanResult* const op0 = clip->FirstOperand->ResolveSelectPtr<IfcBooleanResult>(conv.db)) { + ProcessBoolean(*op0,first_operand,conv); + } + else if (const IfcSweptAreaSolid* const swept = clip->FirstOperand->ResolveSelectPtr<IfcSweptAreaSolid>(conv.db)) { + ProcessSweptAreaSolid(*swept,first_operand,conv); + } + else { + IFCImporter::LogError("expected IfcSweptAreaSolid or IfcBooleanResult as first clipping operand"); + return; + } + + if(hs) { + + const IfcPolygonalBoundedHalfSpace* const hs_bounded = clip->SecondOperand->ResolveSelectPtr<IfcPolygonalBoundedHalfSpace>(conv.db); + if (hs_bounded) { + ProcessPolygonalBoundedBooleanHalfSpaceDifference(hs_bounded, result, first_operand, conv); + } + else { + ProcessBooleanHalfSpaceDifference(hs, result, first_operand, conv); + } + } + else { + ProcessBooleanExtrudedAreaSolidDifference(as, result, first_operand, conv); + } + } + else { + IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is " + boolean.GetClassName()); + } +} + +} // ! IFC +} // ! Assimp + +#endif + diff --git a/src/3rdparty/assimp/code/IFCCurve.cpp b/src/3rdparty/assimp/code/IFCCurve.cpp index e1b79ceeb..4919b52aa 100644 --- a/src/3rdparty/assimp/code/IFCCurve.cpp +++ b/src/3rdparty/assimp/code/IFCCurve.cpp @@ -85,14 +85,18 @@ public: size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { ai_assert(InRange(a) && InRange(b)); - a = fmod(a,static_cast<IfcFloat>( 360. )); - b = fmod(b,static_cast<IfcFloat>( 360. )); - return static_cast<size_t>( abs(ceil(( b-a)) / conv.settings.conicSamplingAngle) ); + a *= conv.angle_scale; + b *= conv.angle_scale; + + a = fmod(a,static_cast<IfcFloat>( AI_MATH_TWO_PI )); + b = fmod(b,static_cast<IfcFloat>( AI_MATH_TWO_PI )); + const IfcFloat setting = static_cast<IfcFloat>( AI_MATH_PI * conv.settings.conicSamplingAngle / 180.0 ); + return static_cast<size_t>( ceil(abs( b-a)) / setting); } // -------------------------------------------------- ParamRange GetParametricRange() const { - return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( 360. )); + return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale )); } protected: @@ -272,7 +276,7 @@ public: IfcFloat acc = 0; BOOST_FOREACH(const CurveEntry& entry, curves) { const ParamRange& range = entry.first->GetParametricRange(); - const IfcFloat delta = range.second-range.first; + const IfcFloat delta = abs(range.second-range.first); if (u < acc+delta) { return entry.first->Eval( entry.second ? (u-acc) + range.first : range.second-(u-acc)); } @@ -291,7 +295,7 @@ public: IfcFloat acc = 0; BOOST_FOREACH(const CurveEntry& entry, curves) { const ParamRange& range = entry.first->GetParametricRange(); - const IfcFloat delta = range.second-range.first; + const IfcFloat delta = abs(range.second-range.first); if (a <= acc+delta && b >= acc) { const IfcFloat at = std::max(static_cast<IfcFloat>( 0. ),a-acc), bt = std::min(delta,b-acc); cnt += entry.first->EstimateSampleCount( entry.second ? at + range.first : range.second - bt, entry.second ? bt + range.first : range.second - at ); @@ -425,6 +429,12 @@ public: } // -------------------------------------------------- + void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const { + ai_assert(InRange(a) && InRange(b)); + return base->SampleDiscrete(out,TrimParam(a),TrimParam(b)); + } + + // -------------------------------------------------- ParamRange GetParametricRange() const { return std::make_pair(static_cast<IfcFloat>( 0. ),maxval); } @@ -540,16 +550,18 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv) return NULL; } -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG // ------------------------------------------------------------------------------------------------ bool Curve :: InRange(IfcFloat u) const { const ParamRange range = GetParametricRange(); if (IsClosed()) { - ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity()); - u = range.first + fmod(u-range.first,range.second-range.first); + return true; + //ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity()); + //u = range.first + fmod(u-range.first,range.second-range.first); } - return u >= range.first && u <= range.second; + const IfcFloat epsilon = 1e-5; + return u - range.first > -epsilon && range.second - u > -epsilon; } #endif @@ -557,7 +569,7 @@ bool Curve :: InRange(IfcFloat u) const IfcFloat Curve :: GetParametricRangeDelta() const { const ParamRange& range = GetParametricRange(); - return range.second - range.first; + return abs(range.second - range.first); } // ------------------------------------------------------------------------------------------------ diff --git a/src/3rdparty/assimp/code/IFCGeometry.cpp b/src/3rdparty/assimp/code/IFCGeometry.cpp index bbf03203b..a3c6711d8 100644 --- a/src/3rdparty/assimp/code/IFCGeometry.cpp +++ b/src/3rdparty/assimp/code/IFCGeometry.cpp @@ -57,14 +57,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { namespace IFC { - using ClipperLib::ulong64; - // XXX use full -+ range ... - const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var - - //#define to_int64(p) (static_cast<ulong64>( std::max( 0., std::min( static_cast<IfcFloat>((p)), 1.) ) * max_ulong64 )) -#define to_int64(p) (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 )) -#define from_int64(p) (static_cast<IfcFloat>((p)) / max_ulong64) - // ------------------------------------------------------------------------------------------------ bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/) { @@ -92,338 +84,123 @@ bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData& } // ------------------------------------------------------------------------------------------------ -void ComputePolygonNormals(const TempMesh& meshout, std::vector<IfcVector3>& normals, bool normalize = true, size_t ofs = 0) -{ - size_t max_vcount = 0; - std::vector<unsigned int>::const_iterator begin=meshout.vertcnt.begin()+ofs, end=meshout.vertcnt.end(), iit; - for(iit = begin; iit != end; ++iit) { - max_vcount = std::max(max_vcount,static_cast<size_t>(*iit)); - } - - std::vector<IfcFloat> temp((max_vcount+2)*4); - normals.reserve( normals.size() + meshout.vertcnt.size()-ofs ); - - // `NewellNormal()` currently has a relatively strange interface and need to - // re-structure things a bit to meet them. - size_t vidx = std::accumulate(meshout.vertcnt.begin(),begin,0); - for(iit = begin; iit != end; vidx += *iit++) { - if (!*iit) { - normals.push_back(IfcVector3()); - continue; - } - for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) { - const IfcVector3& v = meshout.verts[vidx+vofs]; - temp[cnt++] = v.x; - temp[cnt++] = v.y; - temp[cnt++] = v.z; -#ifdef _DEBUG - temp[cnt] = std::numeric_limits<IfcFloat>::quiet_NaN(); -#endif - ++cnt; - } - - normals.push_back(IfcVector3()); - NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]); - } - - if(normalize) { - BOOST_FOREACH(IfcVector3& n, normals) { - n.Normalize(); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// Compute the normal of the last polygon in the given mesh -IfcVector3 ComputePolygonNormal(const TempMesh& inmesh, bool normalize = true) -{ - size_t total = inmesh.vertcnt.back(), vidx = inmesh.verts.size() - total; - std::vector<IfcFloat> temp((total+2)*3); - for(size_t vofs = 0, cnt = 0; vofs < total; ++vofs) { - const IfcVector3& v = inmesh.verts[vidx+vofs]; - temp[cnt++] = v.x; - temp[cnt++] = v.y; - temp[cnt++] = v.z; - } - IfcVector3 nor; - NewellNormal<3,3,3>(nor,total,&temp[0],&temp[1],&temp[2]); - return normalize ? nor.Normalize() : nor; -} - -// ------------------------------------------------------------------------------------------------ -void FixupFaceOrientation(TempMesh& result) +void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = (size_t)-1) { - const IfcVector3 vavg = result.Center(); - - std::vector<IfcVector3> normals; - ComputePolygonNormals(result,normals); - - size_t c = 0, ofs = 0; - BOOST_FOREACH(unsigned int cnt, result.vertcnt) { - if (cnt>2){ - const IfcVector3& thisvert = result.verts[c]; - if (normals[ofs]*(thisvert-vavg) < 0) { - std::reverse(result.verts.begin()+c,result.verts.begin()+cnt+c); - } - } - c += cnt; - ++ofs; - } -} - -// ------------------------------------------------------------------------------------------------ -void RecursiveMergeBoundaries(TempMesh& final_result, const TempMesh& in, const TempMesh& boundary, std::vector<IfcVector3>& normals, const IfcVector3& nor_boundary) -{ - ai_assert(in.vertcnt.size() >= 1); - ai_assert(boundary.vertcnt.size() == 1); - std::vector<unsigned int>::const_iterator end = in.vertcnt.end(), begin=in.vertcnt.begin(), iit, best_iit; - - TempMesh out; - - // iterate through all other bounds and find the one for which the shortest connection - // to the outer boundary is actually the shortest possible. - size_t vidx = 0, best_vidx_start = 0; - size_t best_ofs, best_outer = boundary.verts.size(); - IfcFloat best_dist = 1e10; - for(std::vector<unsigned int>::const_iterator iit = begin; iit != end; vidx += *iit++) { - - for(size_t vofs = 0; vofs < *iit; ++vofs) { - const IfcVector3& v = in.verts[vidx+vofs]; - - for(size_t outer = 0; outer < boundary.verts.size(); ++outer) { - const IfcVector3& o = boundary.verts[outer]; - const IfcFloat d = (o-v).SquareLength(); - - if (d < best_dist) { - best_dist = d; - best_ofs = vofs; - best_outer = outer; - best_iit = iit; - best_vidx_start = vidx; - } - } - } - } - - ai_assert(best_outer != boundary.verts.size()); - - - // now that we collected all vertex connections to be added, build the output polygon - const size_t cnt = boundary.verts.size() + *best_iit+2; - out.verts.reserve(cnt); - - for(size_t outer = 0; outer < boundary.verts.size(); ++outer) { - const IfcVector3& o = boundary.verts[outer]; - out.verts.push_back(o); - - if (outer == best_outer) { - for(size_t i = best_ofs; i < *best_iit; ++i) { - out.verts.push_back(in.verts[best_vidx_start + i]); - } - - // we need the first vertex of the inner polygon twice as we return to the - // outer loop through the very same connection through which we got there. - for(size_t i = 0; i <= best_ofs; ++i) { - out.verts.push_back(in.verts[best_vidx_start + i]); - } - - // reverse face winding if the normal of the sub-polygon points in the - // same direction as the normal of the outer polygonal boundary - if (normals[std::distance(begin,best_iit)] * nor_boundary > 0) { - std::reverse(out.verts.rbegin(),out.verts.rbegin()+*best_iit+1); - } - - // also append a copy of the initial insertion point to be able to continue the outer polygon - out.verts.push_back(o); - } - } - out.vertcnt.push_back(cnt); - ai_assert(out.verts.size() == cnt); - - if (in.vertcnt.size()-std::count(begin,end,0) > 1) { - // Recursively apply the same algorithm if there are more boundaries to merge. The - // current implementation is relatively inefficient, though. - - TempMesh temp; - - // drop the boundary that we just processed - const size_t dist = std::distance(begin, best_iit); - TempMesh remaining = in; - remaining.vertcnt.erase(remaining.vertcnt.begin() + dist); - remaining.verts.erase(remaining.verts.begin()+best_vidx_start,remaining.verts.begin()+best_vidx_start+*best_iit); - - normals.erase(normals.begin() + dist); - RecursiveMergeBoundaries(temp,remaining,out,normals,nor_boundary); - - final_result.Append(temp); + // handle all trivial cases + if(inmesh.vertcnt.empty()) { + return; } - else final_result.Append(out); -} - -// ------------------------------------------------------------------------------------------------ -void MergePolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = -1) -{ - // standard case - only one boundary, just copy it to the result vector - if (inmesh.vertcnt.size() <= 1) { + if(inmesh.vertcnt.size() == 1) { result.Append(inmesh); return; } - result.vertcnt.reserve(inmesh.vertcnt.size()+result.vertcnt.size()); + ai_assert(std::count(inmesh.vertcnt.begin(), inmesh.vertcnt.end(), 0) == 0); - // XXX get rid of the extra copy if possible - TempMesh meshout = inmesh; + typedef std::vector<unsigned int>::const_iterator face_iter; - // handle polygons with holes. Our built in triangulation won't handle them as is, but - // the ear cutting algorithm is solid enough to deal with them if we join the inner - // holes with the outer boundaries by dummy connections. - IFCImporter::LogDebug("fixing polygon with holes for triangulation via ear-cutting"); - std::vector<unsigned int>::iterator outer_polygon = meshout.vertcnt.end(), begin=meshout.vertcnt.begin(), end=outer_polygon, iit; + face_iter begin = inmesh.vertcnt.begin(), end = inmesh.vertcnt.end(), iit; + std::vector<unsigned int>::const_iterator outer_polygon_it = end; - // each hole results in two extra vertices - result.verts.reserve(meshout.verts.size()+meshout.vertcnt.size()*2+result.verts.size()); - size_t outer_polygon_start = 0; + // major task here: given a list of nested polygon boundaries (one of which + // is the outer contour), reduce the triangulation task arising here to + // one that can be solved using the "quadrulation" algorithm which we use + // for pouring windows out of walls. The algorithm does not handle all + // cases but at least it is numerically stable and gives "nice" triangles. + // first compute normals for all polygons using Newell's algorithm // do not normalize 'normals', we need the original length for computing the polygon area std::vector<IfcVector3> normals; - ComputePolygonNormals(meshout,normals,false); + inmesh.ComputePolygonNormals(normals,false); - // see if one of the polygons is a IfcFaceOuterBound (in which case `master_bounds` is its index). - // sadly we can't rely on it, the docs say 'At most one of the bounds shall be of the type IfcFaceOuterBound' + // One of the polygons might be a IfcFaceOuterBound (in which case `master_bounds` + // is its index). Sadly we can't rely on it, the docs say 'At most one of the bounds + // shall be of the type IfcFaceOuterBound' IfcFloat area_outer_polygon = 1e-10f; if (master_bounds != (size_t)-1) { - outer_polygon = begin + master_bounds; - outer_polygon_start = std::accumulate(begin,outer_polygon,0); - area_outer_polygon = normals[master_bounds].SquareLength(); + ai_assert(master_bounds < inmesh.vertcnt.size()); + outer_polygon_it = begin + master_bounds; } else { - size_t vidx = 0; - for(iit = begin; iit != meshout.vertcnt.end(); vidx += *iit++) { - // find the polygon with the largest area, it must be the outer bound. + for(iit = begin; iit != end; iit++) { + // find the polygon with the largest area and take it as the outer bound. IfcVector3& n = normals[std::distance(begin,iit)]; const IfcFloat area = n.SquareLength(); if (area > area_outer_polygon) { area_outer_polygon = area; - outer_polygon = iit; - outer_polygon_start = vidx; + outer_polygon_it = iit; } } } - ai_assert(outer_polygon != meshout.vertcnt.end()); - std::vector<IfcVector3>& in = meshout.verts; + ai_assert(outer_polygon_it != end); - // skip over extremely small boundaries - this is a workaround to fix cases - // in which the number of holes is so extremely large that the - // triangulation code fails. -#define IFC_VERTICAL_HOLE_SIZE_THRESHOLD 0.000001f - size_t vidx = 0, removed = 0, index = 0; - const IfcFloat threshold = area_outer_polygon * IFC_VERTICAL_HOLE_SIZE_THRESHOLD; - for(iit = begin; iit != end ;++index) { - const IfcFloat sqlen = normals[index].SquareLength(); - if (sqlen < threshold) { - std::vector<IfcVector3>::iterator inbase = in.begin()+vidx; - in.erase(inbase,inbase+*iit); - - outer_polygon_start -= outer_polygon_start>vidx ? *iit : 0; - *iit++ = 0; - ++removed; + const size_t outer_polygon_size = *outer_polygon_it; + const IfcVector3& master_normal = normals[std::distance(begin, outer_polygon_it)]; - IFCImporter::LogDebug("skip small hole below threshold"); - } - else { - normals[index] /= sqrt(sqlen); - vidx += *iit++; - } - } + // Generate fake openings to meet the interface for the quadrulate + // algorithm. It boils down to generating small boxes given the + // inner polygon and the surface normal of the outer contour. + // It is important that we use the outer contour's normal because + // this is the plane onto which the quadrulate algorithm will + // project the entire mesh. + std::vector<TempOpening> fake_openings; + fake_openings.reserve(inmesh.vertcnt.size()-1); - // see if one or more of the hole has a face that lies directly on an outer bound. - // this happens for doors, for example. - vidx = 0; - for(iit = begin; ; vidx += *iit++) { -next_loop: - if (iit == end) { - break; - } - if (iit == outer_polygon) { + std::vector<IfcVector3>::const_iterator vit = inmesh.verts.begin(), outer_vit; + + for(iit = begin; iit != end; vit += *iit++) { + if (iit == outer_polygon_it) { + outer_vit = vit; continue; } - for(size_t vofs = 0; vofs < *iit; ++vofs) { - if (!*iit) { - continue; - } - const size_t next = (vofs+1)%*iit; - const IfcVector3& v = in[vidx+vofs], &vnext = in[vidx+next],&vd = (vnext-v).Normalize(); - - for(size_t outer = 0; outer < *outer_polygon; ++outer) { - const IfcVector3& o = in[outer_polygon_start+outer], &onext = in[outer_polygon_start+(outer+1)%*outer_polygon], &od = (onext-o).Normalize(); - - if (fabs(vd * od) > 1.f-1e-6f && (onext-v).Normalize() * vd > 1.f-1e-6f && (onext-v)*(o-v) < 0) { - IFCImporter::LogDebug("got an inner hole that lies partly on the outer polygonal boundary, merging them to a single contour"); - - // in between outer and outer+1 insert all vertices of this loop, then drop the original altogether. - std::vector<IfcVector3> tmp(*iit); - - const size_t start = (v-o).SquareLength() > (vnext-o).SquareLength() ? vofs : next; - std::vector<IfcVector3>::iterator inbase = in.begin()+vidx, it = std::copy(inbase+start, inbase+*iit,tmp.begin()); - std::copy(inbase, inbase+start,it); - std::reverse(tmp.begin(),tmp.end()); + // Filter degenerate polygons to keep them from causing trouble later on + IfcVector3& n = normals[std::distance(begin,iit)]; + const IfcFloat area = n.SquareLength(); + if (area < 1e-5f) { + IFCImporter::LogWarn("skipping degenerate polygon (ProcessPolygonBoundaries)"); + continue; + } - in.insert(in.begin()+outer_polygon_start+(outer+1)%*outer_polygon,tmp.begin(),tmp.end()); - vidx += outer_polygon_start<vidx ? *iit : 0; + fake_openings.push_back(TempOpening()); + TempOpening& opening = fake_openings.back(); - inbase = in.begin()+vidx; - in.erase(inbase,inbase+*iit); + opening.extrusionDir = master_normal; + opening.solid = NULL; - outer_polygon_start -= outer_polygon_start>vidx ? *iit : 0; - - *outer_polygon += tmp.size(); - *iit++ = 0; - ++removed; - goto next_loop; - } - } - } - } + opening.profileMesh = boost::make_shared<TempMesh>(); + opening.profileMesh->verts.reserve(*iit); + opening.profileMesh->vertcnt.push_back(*iit); - if ( meshout.vertcnt.size() - removed <= 1) { - result.Append(meshout); - return; + std::copy(vit, vit + *iit, std::back_inserter(opening.profileMesh->verts)); } - // extract the outer boundary and move it to a separate mesh - TempMesh boundary; - boundary.vertcnt.resize(1,*outer_polygon); - boundary.verts.resize(*outer_polygon); - - std::vector<IfcVector3>::iterator b = in.begin()+outer_polygon_start; - std::copy(b,b+*outer_polygon,boundary.verts.begin()); - in.erase(b,b+*outer_polygon); - - std::vector<IfcVector3>::iterator norit = normals.begin()+std::distance(meshout.vertcnt.begin(),outer_polygon); - const IfcVector3 nor_boundary = *norit; - normals.erase(norit); - meshout.vertcnt.erase(outer_polygon); + // fill a mesh with ONLY the main polygon + TempMesh temp; + temp.verts.reserve(outer_polygon_size); + temp.vertcnt.push_back(outer_polygon_size); + std::copy(outer_vit, outer_vit+outer_polygon_size, + std::back_inserter(temp.verts)); - // keep merging the closest inner boundary with the outer boundary until no more boundaries are left - RecursiveMergeBoundaries(result,meshout,boundary,normals,nor_boundary); + GenerateOpenings(fake_openings, normals, temp, false, false); + result.Append(temp); } - // ------------------------------------------------------------------------------------------------ void ProcessConnectedFaceSet(const IfcConnectedFaceSet& fset, TempMesh& result, ConversionData& conv) { BOOST_FOREACH(const IfcFace& face, fset.CfsFaces) { - // size_t ob = -1, cnt = 0; TempMesh meshout; BOOST_FOREACH(const IfcFaceBound& bound, face.Bounds) { - // XXX implement proper merging for polygonal loops if(const IfcPolyLoop* const polyloop = bound.Bound->ToPtr<IfcPolyLoop>()) { if(ProcessPolyloop(*polyloop, meshout,conv)) { + // The outer boundary is better determined by checking which + // polygon covers the largest area. + //if(bound.ToPtr<IfcFaceOuterBound>()) { // ob = cnt; //} @@ -436,6 +213,9 @@ void ProcessConnectedFaceSet(const IfcConnectedFaceSet& fset, TempMesh& result, continue; } + // And this, even though it is sometimes TRUE and sometimes FALSE, + // does not really improve results. + /*if(!IsTrue(bound.Orientation)) { size_t c = 0; BOOST_FOREACH(unsigned int& c, meshout.vertcnt) { @@ -443,15 +223,11 @@ void ProcessConnectedFaceSet(const IfcConnectedFaceSet& fset, TempMesh& result, cnt += c; } }*/ - } - MergePolygonBoundaries(result,meshout); + ProcessPolygonBoundaries(result, meshout); } } - - - // ------------------------------------------------------------------------------------------------ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv) { @@ -539,865 +315,217 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul IFCImporter::LogDebug("generate mesh procedurally by radial extrusion (IfcRevolvedAreaSolid)"); } -// ------------------------------------------------------------------------------------------------ -IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh) { - - const std::vector<IfcVector3>& out = curmesh.verts; - IfcMatrix3 m; - - const size_t s = out.size(); - assert(curmesh.vertcnt.size() == 1 && curmesh.vertcnt.back() == s); - - const IfcVector3 any_point = out[s-1]; - IfcVector3 nor; - - // The input polygon is arbitrarily shaped, so we might need some tries - // until we find a suitable normal (and it does not even need to be - // right in all cases, Newell's algorithm would be the correct one ... ). - size_t base = s-curmesh.vertcnt.back(), i, j; - for (i = base; i < s-1; ++i) { - for (j = i+1; j < s; ++j) { - nor = -((out[i]-any_point)^(out[j]-any_point)); - if(fabs(nor.Length()) > 1e-8f) { - goto out; - } - } - } - - assert(0); - -out: - - nor.Normalize(); - - IfcVector3 r = (out[i]-any_point); - r.Normalize(); - - // reconstruct orthonormal basis - IfcVector3 u = r ^ nor; - u.Normalize(); - - m.a1 = r.x; - m.a2 = r.y; - m.a3 = r.z; - - m.b1 = u.x; - m.b2 = u.y; - m.b3 = u.z; - - m.c1 = nor.x; - m.c2 = nor.y; - m.c3 = nor.z; - return m; -} // ------------------------------------------------------------------------------------------------ -bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, TempMesh& curmesh) +void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, ConversionData& conv) { - std::vector<IfcVector3>& out = curmesh.verts; - - bool result = false; - - // Try to derive a solid base plane within the current surface for use as - // working coordinate system. - const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh); - const IfcMatrix3 minv = IfcMatrix3(m).Inverse(); - const IfcVector3& nor = IfcVector3(m.c1, m.c2, m.c3); - - IfcFloat coord = -1; - - std::vector<IfcVector2> contour_flat; - contour_flat.reserve(out.size()); - - IfcVector2 vmin, vmax; - MinMaxChooser<IfcVector2>()(vmin, vmax); + const Curve* const curve = Curve::Convert(*solid.Directrix, conv); + if(!curve) { + IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)"); + return; + } - // Move all points into the new coordinate system, collecting min/max verts on the way - BOOST_FOREACH(IfcVector3& x, out) { - const IfcVector3 vv = m * x; - - // keep Z offset in the plane coordinate system. Ignoring precision issues - // (which are present, of course), this should be the same value for - // all polygon vertices (assuming the polygon is planar). + const unsigned int cnt_segments = 16; + const IfcFloat deltaAngle = AI_MATH_TWO_PI/cnt_segments; + const size_t samples = curve->EstimateSampleCount(solid.StartParam,solid.EndParam); - // XXX this should be guarded, but we somehow need to pick a suitable - // epsilon - // if(coord != -1.0f) { - // assert(fabs(coord - vv.z) < 1e-3f); - // } + result.verts.reserve(cnt_segments * samples * 4); + result.vertcnt.reserve((cnt_segments - 1) * samples); - coord = vv.z; + std::vector<IfcVector3> points; + points.reserve(cnt_segments * samples); - vmin = std::min(IfcVector2(vv.x, vv.y), vmin); - vmax = std::max(IfcVector2(vv.x, vv.y), vmax); + TempMesh temp; + curve->SampleDiscrete(temp,solid.StartParam,solid.EndParam); + const std::vector<IfcVector3>& curve_points = temp.verts; - contour_flat.push_back(IfcVector2(vv.x,vv.y)); + if(curve_points.empty()) { + IFCImporter::LogWarn("curve evaluation yielded no points (IfcSweptDiskSolid)"); + return; } - - // With the current code in DerivePlaneCoordinateSpace, - // vmin,vmax should always be the 0...1 rectangle (+- numeric inaccuracies) - // but here we won't rely on this. - - vmax -= vmin; - - // If this happens then the projection must have been wrong. - assert(vmax.Length()); - - ClipperLib::ExPolygons clipped; - ClipperLib::Polygons holes_union; - - - IfcVector3 wall_extrusion; - bool do_connections = false, first = true; - - try { - - ClipperLib::Clipper clipper_holes; - size_t c = 0; - - BOOST_FOREACH(const TempOpening& t,openings) { - const IfcVector3& outernor = nors[c++]; - const IfcFloat dot = nor * outernor; - if (fabs(dot)<1.f-1e-6f) { - continue; - } - - const std::vector<IfcVector3>& va = t.profileMesh->verts; - if(va.size() <= 2) { - continue; - } - - std::vector<IfcVector2> contour; - - BOOST_FOREACH(const IfcVector3& xx, t.profileMesh->verts) { - IfcVector3 vv = m * xx, vv_extr = m * (xx + t.extrusionDir); - - const bool is_extruded_side = fabs(vv.z - coord) > fabs(vv_extr.z - coord); - if (first) { - first = false; - if (dot > 0.f) { - do_connections = true; - wall_extrusion = t.extrusionDir; - if (is_extruded_side) { - wall_extrusion = - wall_extrusion; - } - } - } - - // XXX should not be necessary - but it is. Why? For precision reasons? - vv = is_extruded_side ? vv_extr : vv; - contour.push_back(IfcVector2(vv.x,vv.y)); - } - - ClipperLib::Polygon hole; - BOOST_FOREACH(IfcVector2& pip, contour) { - pip.x = (pip.x - vmin.x) / vmax.x; - pip.y = (pip.y - vmin.y) / vmax.y; - - hole.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); - } - - if (!ClipperLib::Orientation(hole)) { - std::reverse(hole.begin(), hole.end()); - // assert(ClipperLib::Orientation(hole)); - } - - /*ClipperLib::Polygons pol_temp(1), pol_temp2(1); - pol_temp[0] = hole; - - ClipperLib::OffsetPolygons(pol_temp,pol_temp2,5.0); - hole = pol_temp2[0];*/ - - clipper_holes.AddPolygon(hole,ClipperLib::ptSubject); - } - - clipper_holes.Execute(ClipperLib::ctUnion,holes_union, - ClipperLib::pftNonZero, - ClipperLib::pftNonZero); - if (holes_union.empty()) { - return false; - } + IfcVector3 current = curve_points[0]; + IfcVector3 previous = current; + IfcVector3 next; - // Now that we have the big union of all holes, subtract it from the outer contour - // to obtain the final polygon to feed into the triangulator. - { - ClipperLib::Polygon poly; - BOOST_FOREACH(IfcVector2& pip, contour_flat) { - pip.x = (pip.x - vmin.x) / vmax.x; - pip.y = (pip.y - vmin.y) / vmax.y; + IfcVector3 startvec; + startvec.x = 1.0f; + startvec.y = 1.0f; + startvec.z = 1.0f; - poly.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); - } + unsigned int last_dir = 0; - if (ClipperLib::Orientation(poly)) { - std::reverse(poly.begin(), poly.end()); - } - clipper_holes.Clear(); - clipper_holes.AddPolygon(poly,ClipperLib::ptSubject); + // generate circles at the sweep positions + for(size_t i = 0; i < samples; ++i) { - clipper_holes.AddPolygons(holes_union,ClipperLib::ptClip); - clipper_holes.Execute(ClipperLib::ctDifference,clipped, - ClipperLib::pftNonZero, - ClipperLib::pftNonZero); + if(i != samples - 1) { + next = curve_points[i + 1]; } - } - catch (const char* sx) { - IFCImporter::LogError("Ifc: error during polygon clipping, skipping openings for this face: (Clipper: " - + std::string(sx) + ")"); - - return false; - } - - std::vector<IfcVector3> old_verts; - std::vector<unsigned int> old_vertcnt; - - old_verts.swap(curmesh.verts); - old_vertcnt.swap(curmesh.vertcnt); - - - // add connection geometry to close the adjacent 'holes' for the openings - // this should only be done from one side of the wall or the polygons - // would be emitted twice. - if (false && do_connections) { - - std::vector<IfcVector3> tmpvec; - BOOST_FOREACH(ClipperLib::Polygon& opening, holes_union) { - - assert(ClipperLib::Orientation(opening)); - - tmpvec.clear(); - - BOOST_FOREACH(ClipperLib::IntPoint& point, opening) { - - tmpvec.push_back( minv * IfcVector3( - vmin.x + from_int64(point.X) * vmax.x, - vmin.y + from_int64(point.Y) * vmax.y, - coord)); - } - - for(size_t i = 0, size = tmpvec.size(); i < size; ++i) { - const size_t next = (i+1)%size; - - curmesh.vertcnt.push_back(4); - - const IfcVector3& in_world = tmpvec[i]; - const IfcVector3& next_world = tmpvec[next]; - - // Assumptions: no 'partial' openings, wall thickness roughly the same across the wall - curmesh.verts.push_back(in_world); - curmesh.verts.push_back(in_world+wall_extrusion); - curmesh.verts.push_back(next_world+wall_extrusion); - curmesh.verts.push_back(next_world); - } - } - } + // get a direction vector reflecting the approximate curvature (i.e. tangent) + IfcVector3 d = (current-previous) + (next-previous); - std::vector< std::vector<p2t::Point*> > contours; - BOOST_FOREACH(ClipperLib::ExPolygon& clip, clipped) { - - contours.clear(); - - // Build the outer polygon contour line for feeding into poly2tri - std::vector<p2t::Point*> contour_points; - BOOST_FOREACH(ClipperLib::IntPoint& point, clip.outer) { - contour_points.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) ); - } - - p2t::CDT* cdt ; - try { - // Note: this relies on custom modifications in poly2tri to raise runtime_error's - // instead if assertions. These failures are not debug only, they can actually - // happen in production use if the input data is broken. An assertion would be - // inappropriate. - cdt = new p2t::CDT(contour_points); - } - catch(const std::exception& e) { - IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: " - + std::string(e.what()) + ")"); - continue; - } - - - // Build the poly2tri inner contours for all holes we got from ClipperLib - BOOST_FOREACH(ClipperLib::Polygon& opening, clip.holes) { - - contours.push_back(std::vector<p2t::Point*>()); - std::vector<p2t::Point*>& contour = contours.back(); - - BOOST_FOREACH(ClipperLib::IntPoint& point, opening) { - contour.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) ); + d.Normalize(); + + // figure out an arbitrary point q so that (p-q) * d = 0, + // try to maximize ||(p-q)|| * ||(p_last-q_last)|| + IfcVector3 q; + bool take_any = false; + + for (unsigned int i = 0; i < 2; ++i, take_any = true) { + if ((last_dir == 0 || take_any) && abs(d.x) > 1e-6) { + q.y = startvec.y; + q.z = startvec.z; + q.x = -(d.y * q.y + d.z * q.z) / d.x; + last_dir = 0; + break; } - - cdt->AddHole(contour); - } - - try { - // Note: See above - cdt->Triangulate(); - } - catch(const std::exception& e) { - IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: " - + std::string(e.what()) + ")"); - continue; - } - - const std::vector<p2t::Triangle*>& tris = cdt->GetTriangles(); - - // Collect the triangles we just produced - BOOST_FOREACH(p2t::Triangle* tri, tris) { - for(int i = 0; i < 3; ++i) { - - const IfcVector2& v = IfcVector2( - static_cast<IfcFloat>( tri->GetPoint(i)->x ), - static_cast<IfcFloat>( tri->GetPoint(i)->y ) - ); - - assert(v.x <= 1.0 && v.x >= 0.0 && v.y <= 1.0 && v.y >= 0.0); - const IfcVector3 v3 = minv * IfcVector3(vmin.x + v.x * vmax.x, vmin.y + v.y * vmax.y,coord) ; - - curmesh.verts.push_back(v3); + else if ((last_dir == 1 || take_any) && abs(d.y) > 1e-6) { + q.x = startvec.x; + q.z = startvec.z; + q.y = -(d.x * q.x + d.z * q.z) / d.y; + last_dir = 1; + break; + } + else if ((last_dir == 2 && abs(d.z) > 1e-6) || take_any) { + q.y = startvec.y; + q.x = startvec.x; + q.z = -(d.y * q.y + d.x * q.x) / d.z; + last_dir = 2; + break; } - curmesh.vertcnt.push_back(3); - } - - result = true; - } - - if (!result) { - // revert -- it's a shame, but better than nothing - curmesh.verts.insert(curmesh.verts.end(),old_verts.begin(), old_verts.end()); - curmesh.vertcnt.insert(curmesh.vertcnt.end(),old_vertcnt.begin(), old_vertcnt.end()); - - IFCImporter::LogError("Ifc: revert, could not generate openings for this wall"); - } - - return result; -} - -// ------------------------------------------------------------------------------------------------ -struct DistanceSorter { - - DistanceSorter(const IfcVector3& base) : base(base) {} - - bool operator () (const TempOpening& a, const TempOpening& b) const { - return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength(); - } - - IfcVector3 base; -}; - -// ------------------------------------------------------------------------------------------------ -struct XYSorter { - - // sort first by X coordinates, then by Y coordinates - bool operator () (const IfcVector2&a, const IfcVector2& b) const { - if (a.x == b.x) { - return a.y < b.y; } - return a.x < b.x; - } -}; - -typedef std::pair< IfcVector2, IfcVector2 > BoundingBox; -typedef std::map<IfcVector2,size_t,XYSorter> XYSortedField; + q *= solid.Radius / q.Length(); + startvec = q; -// ------------------------------------------------------------------------------------------------ -void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField& field, const std::vector< BoundingBox >& bbs, - std::vector<IfcVector2>& out) -{ - if (!(pmin.x-pmax.x) || !(pmin.y-pmax.y)) { - return; - } + // generate a rotation matrix to rotate q around d + IfcMatrix4 rot; + IfcMatrix4::Rotation(deltaAngle,d,rot); - IfcFloat xs = 1e10, xe = 1e10; - bool found = false; - - // Search along the x-axis until we find an opening - XYSortedField::iterator start = field.begin(); - for(; start != field.end(); ++start) { - const BoundingBox& bb = bbs[(*start).second]; - if(bb.first.x >= pmax.x) { - break; - } - - if (bb.second.x > pmin.x && bb.second.y > pmin.y && bb.first.y < pmax.y) { - xs = bb.first.x; - xe = bb.second.x; - found = true; - break; + for (unsigned int seg = 0; seg < cnt_segments; ++seg, q *= rot ) { + points.push_back(q + current); } - } - if (!found) { - // the rectangle [pmin,pend] is opaque, fill it - out.push_back(pmin); - out.push_back(IfcVector2(pmin.x,pmax.y)); - out.push_back(pmax); - out.push_back(IfcVector2(pmax.x,pmin.y)); - return; + previous = current; + current = next; } - xs = std::max(pmin.x,xs); - xe = std::min(pmax.x,xe); - - // see if there's an offset to fill at the top of our quad - if (xs - pmin.x) { - out.push_back(pmin); - out.push_back(IfcVector2(pmin.x,pmax.y)); - out.push_back(IfcVector2(xs,pmax.y)); - out.push_back(IfcVector2(xs,pmin.y)); - } + // make quads + for(size_t i = 0; i < samples - 1; ++i) { - // search along the y-axis for all openings that overlap xs and our quad - IfcFloat ylast = pmin.y; - found = false; - for(; start != field.end(); ++start) { - const BoundingBox& bb = bbs[(*start).second]; - if (bb.first.x > xs || bb.first.y >= pmax.y) { - break; - } + const aiVector3D& this_start = points[ i * cnt_segments ]; - if (bb.second.y > ylast) { + // locate corresponding point on next sample ring + unsigned int best_pair_offset = 0; + float best_distance_squared = 1e10f; + for (unsigned int seg = 0; seg < cnt_segments; ++seg) { + const aiVector3D& p = points[ (i+1) * cnt_segments + seg]; + const float l = (p-this_start).SquareLength(); - found = true; - const IfcFloat ys = std::max(bb.first.y,pmin.y), ye = std::min(bb.second.y,pmax.y); - if (ys - ylast) { - QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,ys) ,field,bbs,out); - } - - // the following are the window vertices - - /*wnd.push_back(IfcVector2(xs,ys)); - wnd.push_back(IfcVector2(xs,ye)); - wnd.push_back(IfcVector2(xe,ye)); - wnd.push_back(IfcVector2(xe,ys));*/ - ylast = ye; - } - } - if (!found) { - // the rectangle [pmin,pend] is opaque, fill it - out.push_back(IfcVector2(xs,pmin.y)); - out.push_back(IfcVector2(xs,pmax.y)); - out.push_back(IfcVector2(xe,pmax.y)); - out.push_back(IfcVector2(xe,pmin.y)); - return; - } - if (ylast < pmax.y) { - QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,pmax.y) ,field,bbs,out); - } - - // now for the whole rest - if (pmax.x-xe) { - QuadrifyPart(IfcVector2(xe,pmin.y), pmax ,field,bbs,out); - } -} - -// ------------------------------------------------------------------------------------------------ -void InsertWindowContours(const std::vector< BoundingBox >& bbs, - const std::vector< std::vector<IfcVector2> >& contours, - const std::vector<TempOpening>& /*openings*/, - const std::vector<IfcVector3>& /*nors*/, - const IfcMatrix3& minv, - const IfcVector2& scale, - const IfcVector2& offset, - IfcFloat coord, - TempMesh& curmesh) -{ - ai_assert(contours.size() == bbs.size()); - - // fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now - for(size_t i = 0; i < contours.size();++i) { - const BoundingBox& bb = bbs[i]; - const std::vector<IfcVector2>& contour = contours[i]; - - // check if we need to do it at all - many windows just fit perfectly into their quadratic holes, - // i.e. their contours *are* already their bounding boxes. - if (contour.size() == 4) { - std::set<IfcVector2,XYSorter> verts; - for(size_t n = 0; n < 4; ++n) { - verts.insert(contour[n]); - } - const std::set<IfcVector2,XYSorter>::const_iterator end = verts.end(); - if (verts.find(bb.first)!=end && verts.find(bb.second)!=end - && verts.find(IfcVector2(bb.first.x,bb.second.y))!=end - && verts.find(IfcVector2(bb.second.x,bb.first.y))!=end - ) { - continue; + if(l < best_distance_squared) { + best_pair_offset = seg; + best_distance_squared = l; } } - const IfcFloat diag = (bb.first-bb.second).Length(); - const IfcFloat epsilon = diag/1000.f; + for (unsigned int seg = 0; seg < cnt_segments; ++seg) { - // walk through all contour points and find those that lie on the BB corner - size_t last_hit = -1, very_first_hit = -1; - IfcVector2 edge; - for(size_t n = 0, e=0, size = contour.size();; n=(n+1)%size, ++e) { + result.verts.push_back(points[ i * cnt_segments + (seg % cnt_segments)]); + result.verts.push_back(points[ i * cnt_segments + (seg + 1) % cnt_segments]); + result.verts.push_back(points[ (i+1) * cnt_segments + ((seg + 1 + best_pair_offset) % cnt_segments)]); + result.verts.push_back(points[ (i+1) * cnt_segments + ((seg + best_pair_offset) % cnt_segments)]); - // sanity checking - if (e == size*2) { - IFCImporter::LogError("encountered unexpected topology while generating window contour"); - break; - } + IfcVector3& v1 = *(result.verts.end()-1); + IfcVector3& v2 = *(result.verts.end()-2); + IfcVector3& v3 = *(result.verts.end()-3); + IfcVector3& v4 = *(result.verts.end()-4); - const IfcVector2& v = contour[n]; + if (((v4-v3) ^ (v4-v1)) * (v4 - curve_points[i]) < 0.0f) { + std::swap(v4, v1); + std::swap(v3, v2); + } - bool hit = false; - if (fabs(v.x-bb.first.x)<epsilon) { - edge.x = bb.first.x; - hit = true; - } - else if (fabs(v.x-bb.second.x)<epsilon) { - edge.x = bb.second.x; - hit = true; - } - - if (fabs(v.y-bb.first.y)<epsilon) { - edge.y = bb.first.y; - hit = true; - } - else if (fabs(v.y-bb.second.y)<epsilon) { - edge.y = bb.second.y; - hit = true; - } - - if (hit) { - if (last_hit != (size_t)-1) { - - const size_t old = curmesh.verts.size(); - size_t cnt = last_hit > n ? size-(last_hit-n) : n-last_hit; - for(size_t a = last_hit, e = 0; e <= cnt; a=(a+1)%size, ++e) { - // hack: this is to fix cases where opening contours are self-intersecting. - // Clipper doesn't produce such polygons, but as soon as we're back in - // our brave new floating-point world, very small distances are consumed - // by the maximum available precision, leading to self-intersecting - // polygons. This fix makes concave windows fail even worse, but - // anyway, fail is fail. - if ((contour[a] - edge).SquareLength() > diag*diag*0.7) { - continue; - } - const IfcVector3 v3 = minv * IfcVector3(offset.x + contour[a].x * scale.x, offset.y + contour[a].y * scale.y,coord); - curmesh.verts.push_back(v3); - } - - if (edge != contour[last_hit]) { - - IfcVector2 corner = edge; - - if (fabs(contour[last_hit].x-bb.first.x)<epsilon) { - corner.x = bb.first.x; - } - else if (fabs(contour[last_hit].x-bb.second.x)<epsilon) { - corner.x = bb.second.x; - } - - if (fabs(contour[last_hit].y-bb.first.y)<epsilon) { - corner.y = bb.first.y; - } - else if (fabs(contour[last_hit].y-bb.second.y)<epsilon) { - corner.y = bb.second.y; - } - - const IfcVector3 v3 = minv * IfcVector3(offset.x + corner.x * scale.x, offset.y + corner.y * scale.y,coord); - curmesh.verts.push_back(v3); - } - else if (cnt == 1) { - // avoid degenerate polygons (also known as lines or points) - curmesh.verts.erase(curmesh.verts.begin()+old,curmesh.verts.end()); - } - - if (const size_t d = curmesh.verts.size()-old) { - curmesh.vertcnt.push_back(d); - std::reverse(curmesh.verts.rbegin(),curmesh.verts.rbegin()+d); - } - if (n == very_first_hit) { - break; - } - } - else { - very_first_hit = n; - } - - last_hit = n; - } + result.vertcnt.push_back(4); } } -} - -// ------------------------------------------------------------------------------------------------ -void MergeContours (const std::vector<IfcVector2>& a, const std::vector<IfcVector2>& b, ClipperLib::ExPolygons& out) -{ - ClipperLib::Clipper clipper; - ClipperLib::Polygon clip; - - BOOST_FOREACH(const IfcVector2& pip, a) { - clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); - } - - if (ClipperLib::Orientation(clip)) { - std::reverse(clip.begin(), clip.end()); - } - - clipper.AddPolygon(clip, ClipperLib::ptSubject); - clip.clear(); - - BOOST_FOREACH(const IfcVector2& pip, b) { - clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); - } - if (ClipperLib::Orientation(clip)) { - std::reverse(clip.begin(), clip.end()); - } - - clipper.AddPolygon(clip, ClipperLib::ptSubject); - clipper.Execute(ClipperLib::ctUnion, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero); + IFCImporter::LogDebug("generate mesh procedurally by sweeping a disk along a curve (IfcSweptDiskSolid)"); } // ------------------------------------------------------------------------------------------------ -bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, TempMesh& curmesh) +IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut) { - std::vector<IfcVector3>& out = curmesh.verts; - - // Try to derive a solid base plane within the current surface for use as - // working coordinate system. - const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh); - const IfcMatrix3 minv = IfcMatrix3(m).Inverse(); - const IfcVector3& nor = IfcVector3(m.c1, m.c2, m.c3); - - IfcFloat coord = -1; - - std::vector<IfcVector2> contour_flat; - contour_flat.reserve(out.size()); - - IfcVector2 vmin, vmax; - MinMaxChooser<IfcVector2>()(vmin, vmax); - - // Move all points into the new coordinate system, collecting min/max verts on the way - BOOST_FOREACH(IfcVector3& x, out) { - const IfcVector3 vv = m * x; - - // keep Z offset in the plane coordinate system. Ignoring precision issues - // (which are present, of course), this should be the same value for - // all polygon vertices (assuming the polygon is planar). - - - // XXX this should be guarded, but we somehow need to pick a suitable - // epsilon - // if(coord != -1.0f) { - // assert(fabs(coord - vv.z) < 1e-3f); - // } - - coord = vv.z; - vmin = std::min(IfcVector2(vv.x, vv.y), vmin); - vmax = std::max(IfcVector2(vv.x, vv.y), vmax); - - contour_flat.push_back(IfcVector2(vv.x,vv.y)); - } - - // With the current code in DerivePlaneCoordinateSpace, - // vmin,vmax should always be the 0...1 rectangle (+- numeric inaccuracies) - // but here we won't rely on this. - - vmax -= vmin; - BOOST_FOREACH(IfcVector2& vv, contour_flat) { - vv.x = (vv.x - vmin.x) / vmax.x; - vv.y = (vv.y - vmin.y) / vmax.y; - } - - // project all points into the coordinate system defined by the p+sv*tu plane - // and compute bounding boxes for them - std::vector< BoundingBox > bbs; - std::vector< std::vector<IfcVector2> > contours; - - size_t c = 0; - BOOST_FOREACH(const TempOpening& t,openings) { - const IfcVector3& outernor = nors[c++]; - const IfcFloat dot = nor * outernor; - if (fabs(dot)<1.f-1e-6f) { - continue; - } - - const std::vector<IfcVector3>& va = t.profileMesh->verts; - if(va.size() <= 2) { - continue; - } - - IfcVector2 vpmin,vpmax; - MinMaxChooser<IfcVector2>()(vpmin,vpmax); - - std::vector<IfcVector2> contour; - - BOOST_FOREACH(const IfcVector3& x, t.profileMesh->verts) { - const IfcVector3 v = m * x; - - IfcVector2 vv(v.x, v.y); - - // rescale - vv.x = (vv.x - vmin.x) / vmax.x; - vv.y = (vv.y - vmin.y) / vmax.y; - - vpmin = std::min(vpmin,vv); - vpmax = std::max(vpmax,vv); - - contour.push_back(vv); - } - - BoundingBox bb = BoundingBox(vpmin,vpmax); - - // see if this BB intersects any other, in which case we could not use the Quadrify() - // algorithm and would revert to Poly2Tri only. - for (std::vector<BoundingBox>::iterator it = bbs.begin(); it != bbs.end();) { - const BoundingBox& ibb = *it; - - if (ibb.first.x < bb.second.x && ibb.second.x > bb.first.x && - ibb.first.y < bb.second.y && ibb.second.y > bb.second.x) { - - // take these two contours and try to merge them. If they overlap (which - // should not happen, but in fact happens-in-the-real-world [tm] ), - // resume using a single contour and a single bounding box. - const std::vector<IfcVector2>& other = contours[std::distance(bbs.begin(),it)]; + const std::vector<IfcVector3>& out = curmesh.verts; + IfcMatrix3 m; - ClipperLib::ExPolygons poly; - MergeContours(contour, other, poly); + ok = true; - if (poly.size() > 1) { - IFCImporter::LogWarn("cannot use quadrify algorithm to generate wall openings due to " - "bounding box overlaps, using poly2tri fallback"); - return TryAddOpenings_Poly2Tri(openings, nors, curmesh); - } - else if (poly.size() == 0) { - IFCImporter::LogWarn("ignoring duplicate opening"); - contour.clear(); - break; - } - else { - IFCImporter::LogDebug("merging oberlapping openings, this should not happen"); - - contour.clear(); - BOOST_FOREACH(const ClipperLib::IntPoint& point, poly[0].outer) { - contour.push_back( IfcVector2( from_int64(point.X), from_int64(point.Y))); - } + // The input "mesh" must be a single polygon + const size_t s = out.size(); + assert(curmesh.vertcnt.size() == 1 && curmesh.vertcnt.back() == s); - bb.first = std::min(bb.first, ibb.first); - bb.second = std::max(bb.second, ibb.second); + const IfcVector3 any_point = out[s-1]; + IfcVector3 nor; - contours.erase(contours.begin() + std::distance(bbs.begin(),it)); - it = bbs.erase(it); - continue; - } + // The input polygon is arbitrarily shaped, therefore we might need some tries + // until we find a suitable normal. Note that Newell's algorithm would give + // a more robust result, but this variant also gives us a suitable first + // axis for the 2D coordinate space on the polygon plane, exploiting the + // fact that the input polygon is nearly always a quad. + bool done = false; + size_t i, j; + for (i = 0; !done && i < s-2; done || ++i) { + for (j = i+1; j < s-1; ++j) { + nor = -((out[i]-any_point)^(out[j]-any_point)); + if(fabs(nor.Length()) > 1e-8f) { + done = true; + break; } - ++it; - } - - if(contour.size()) { - contours.push_back(contour); - bbs.push_back(bb); } } - if (bbs.empty()) { - return false; - } - - XYSortedField field; - for (std::vector<BoundingBox>::iterator it = bbs.begin(); it != bbs.end(); ++it) { - if (field.find((*it).first) != field.end()) { - IFCImporter::LogWarn("constraint failure during generation of wall openings, results may be faulty"); - } - field[(*it).first] = std::distance(bbs.begin(),it); + if(!done) { + ok = false; + return m; } - std::vector<IfcVector2> outflat; - outflat.reserve(openings.size()*4); - QuadrifyPart(IfcVector2(0.f,0.f),IfcVector2(1.f,1.f),field,bbs,outflat); - ai_assert(!(outflat.size() % 4)); - - std::vector<IfcVector3> vold; - std::vector<unsigned int> iold; - - vold.reserve(outflat.size()); - iold.reserve(outflat.size() / 4); - - // Fix the outer contour using polyclipper - try { - - ClipperLib::Polygon subject; - ClipperLib::Clipper clipper; - ClipperLib::ExPolygons clipped; - - ClipperLib::Polygon clip; - clip.reserve(contour_flat.size()); - BOOST_FOREACH(const IfcVector2& pip, contour_flat) { - clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); - } - - if (!ClipperLib::Orientation(clip)) { - std::reverse(clip.begin(), clip.end()); - } + nor.Normalize(); + norOut = nor; - // We need to run polyclipper on every single quad -- we can't run it one all - // of them at once or it would merge them all together which would undo all - // previous steps - subject.reserve(4); - size_t cnt = 0; - BOOST_FOREACH(const IfcVector2& pip, outflat) { - subject.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); - if (!(++cnt % 4)) { - if (!ClipperLib::Orientation(subject)) { - std::reverse(subject.begin(), subject.end()); - } - - clipper.AddPolygon(subject,ClipperLib::ptSubject); - clipper.AddPolygon(clip,ClipperLib::ptClip); - - clipper.Execute(ClipperLib::ctIntersection,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero); - - BOOST_FOREACH(const ClipperLib::ExPolygon& ex, clipped) { - iold.push_back(ex.outer.size()); - BOOST_FOREACH(const ClipperLib::IntPoint& point, ex.outer) { - vold.push_back( minv * IfcVector3( - vmin.x + from_int64(point.X) * vmax.x, - vmin.y + from_int64(point.Y) * vmax.y, - coord)); - } - } + IfcVector3 r = (out[i]-any_point); + r.Normalize(); - subject.clear(); - clipped.clear(); - clipper.Clear(); - } - } + //if(d) { + // *d = -any_point * nor; + //} - assert(!(cnt % 4)); - } - catch (const char* sx) { - IFCImporter::LogError("Ifc: error during polygon clipping, contour line may be wrong: (Clipper: " - + std::string(sx) + ")"); + // Reconstruct orthonormal basis + // XXX use Gram Schmidt for increased robustness + IfcVector3 u = r ^ nor; + u.Normalize(); - iold.resize(outflat.size()/4,4); + m.a1 = r.x; + m.a2 = r.y; + m.a3 = r.z; - BOOST_FOREACH(const IfcVector2& vproj, outflat) { - const IfcVector3 v3 = minv * IfcVector3(vmin.x + vproj.x * vmax.x, vmin.y + vproj.y * vmax.y,coord); - vold.push_back(v3); - } - } + m.b1 = u.x; + m.b2 = u.y; + m.b3 = u.z; - // undo the projection, generate output quads - std::swap(vold,curmesh.verts); - std::swap(iold,curmesh.vertcnt); + m.c1 = -nor.x; + m.c2 = -nor.y; + m.c3 = -nor.z; - InsertWindowContours(bbs,contours,openings, nors,minv,vmax, vmin, coord, curmesh); - return true; + return m; } // ------------------------------------------------------------------------------------------------ -void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result, ConversionData& conv) +void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result, + ConversionData& conv, bool collect_openings) { TempMesh meshout; @@ -1409,7 +537,10 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul IfcVector3 dir; ConvertDirection(dir,solid.ExtrudedDirection); - dir *= solid.Depth; + dir *= solid.Depth; /* + if(conv.collect_openings && !conv.apply_openings) { + dir *= 1000.0; + } */ // Outline: assuming that `meshout.verts` is now a list of vertex points forming // the underlying profile, extrude along the given axis, forming new @@ -1419,9 +550,9 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul const size_t size=in.size(); const bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2; - if(solid.Depth < 1e-3) { + if(solid.Depth < 1e-6) { if(has_area) { - meshout = result; + result = meshout; } return; } @@ -1432,9 +563,18 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul // First step: transform all vertices into the target coordinate space IfcMatrix4 trafo; ConvertAxisPlacement(trafo, solid.Position); + + IfcVector3 vmin, vmax; + MinMaxChooser<IfcVector3>()(vmin, vmax); BOOST_FOREACH(IfcVector3& v,in) { v *= trafo; + + vmin = std::min(vmin, v); + vmax = std::max(vmax, v); } + + vmax -= vmin; + const IfcFloat diag = vmax.Length(); IfcVector3 min = in[0]; dir *= IfcMatrix3(trafo); @@ -1444,6 +584,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul // Compute the normal vectors for all opening polygons as a prerequisite // to TryAddOpenings_Poly2Tri() + // XXX this belongs into the aforementioned function if (openings) { if (!conv.settings.useCustomTriangulation) { @@ -1451,7 +592,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul // doesn't matter, but we would screw up if we started with e.g. a door in between // two windows. std::sort(conv.apply_openings->begin(),conv.apply_openings->end(), - DistanceSorter(min)); + TempOpening::DistanceSorter(min)); } nors.reserve(conv.apply_openings->size()); @@ -1483,7 +624,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul out.push_back(in[next]); if(openings) { - if(TryAddOpenings_Quadrulate(*conv.apply_openings,nors,temp)) { + if((in[i]-in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) { ++sides_with_openings; } @@ -1491,6 +632,15 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul temp.Clear(); } } + + if(openings) { + BOOST_FOREACH(TempOpening& opening, *conv.apply_openings) { + if (!opening.wallPoints.empty()) { + IFCImporter::LogError("failed to generate all window caps"); + } + opening.wallPoints.clear(); + } + } size_t sides_with_v_openings = 0; if(has_area) { @@ -1502,7 +652,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul curmesh.vertcnt.push_back(size); if(openings && size > 2) { - if(TryAddOpenings_Quadrulate(*conv.apply_openings,nors,temp)) { + if(GenerateOpenings(*conv.apply_openings,nors,temp,true, true, dir)) { ++sides_with_v_openings; } @@ -1512,37 +662,33 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul } } - - if(openings && ((sides_with_openings != 2 && sides_with_openings) || (sides_with_v_openings != 2 && sides_with_v_openings))) { + if(openings && ((sides_with_openings == 1 && sides_with_openings) || (sides_with_v_openings == 2 && sides_with_v_openings))) { IFCImporter::LogWarn("failed to resolve all openings, presumably their topology is not supported by Assimp"); } IFCImporter::LogDebug("generate mesh procedurally by extrusion (IfcExtrudedAreaSolid)"); -} + // If this is an opening element, store both the extruded mesh and the 2D profile mesh + // it was created from. Return an empty mesh to the caller. + if(collect_openings && !result.IsEmpty()) { + ai_assert(conv.collect_openings); + boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh()); + profile->Swap(result); + boost::shared_ptr<TempMesh> profile2D = boost::shared_ptr<TempMesh>(new TempMesh()); + profile2D->Swap(meshout); + conv.collect_openings->push_back(TempOpening(&solid,dir,profile, profile2D)); + + ai_assert(result.IsEmpty()); + } +} // ------------------------------------------------------------------------------------------------ -void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, ConversionData& conv) +void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, + ConversionData& conv) { if(const IfcExtrudedAreaSolid* const solid = swept.ToPtr<IfcExtrudedAreaSolid>()) { - // Do we just collect openings for a parent element (i.e. a wall)? - // In this case we don't extrude the surface yet, just keep the profile and transform it correctly - if(conv.collect_openings) { - boost::shared_ptr<TempMesh> meshtmp(new TempMesh()); - ProcessProfile(swept.SweptArea,*meshtmp,conv); - - IfcMatrix4 m; - ConvertAxisPlacement(m,solid->Position); - meshtmp->Transform(m); - - IfcVector3 dir; - ConvertDirection(dir,solid->ExtrudedDirection); - conv.collect_openings->push_back(TempOpening(solid, IfcMatrix3(m) * (dir*static_cast<IfcFloat>(solid->Depth)),meshtmp)); - return; - } - - ProcessExtrudedAreaSolid(*solid,meshout,conv); + ProcessExtrudedAreaSolid(*solid,meshout,conv, !!conv.collect_openings); } else if(const IfcRevolvedAreaSolid* const rev = swept.ToPtr<IfcRevolvedAreaSolid>()) { ProcessRevolvedAreaSolid(*rev,meshout,conv); @@ -1552,165 +698,19 @@ void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, Co } } - -// ------------------------------------------------------------------------------------------------ -enum Intersect { - Intersect_No, - Intersect_LiesOnPlane, - Intersect_Yes -}; - // ------------------------------------------------------------------------------------------------ -Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const IfcVector3& e0, const IfcVector3& e1, IfcVector3& out) +bool ProcessGeometricItem(const IfcRepresentationItem& geo, std::vector<unsigned int>& mesh_indices, + ConversionData& conv) { - const IfcVector3 pdelta = e0 - p, seg = e1-e0; - const IfcFloat dotOne = n*seg, dotTwo = -(n*pdelta); - - if (fabs(dotOne) < 1e-6) { - return fabs(dotTwo) < 1e-6f ? Intersect_LiesOnPlane : Intersect_No; - } - - const IfcFloat t = dotTwo/dotOne; - // t must be in [0..1] if the intersection point is within the given segment - if (t > 1.f || t < 0.f) { - return Intersect_No; - } - out = e0+t*seg; - return Intersect_Yes; -} - -// ------------------------------------------------------------------------------------------------ -void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv) -{ - if(const IfcBooleanResult* const clip = boolean.ToPtr<IfcBooleanResult>()) { - if(clip->Operator != "DIFFERENCE") { - IFCImporter::LogWarn("encountered unsupported boolean operator: " + (std::string)clip->Operator); - return; - } - - TempMesh meshout; - const IfcHalfSpaceSolid* const hs = clip->SecondOperand->ResolveSelectPtr<IfcHalfSpaceSolid>(conv.db); - if(!hs) { - IFCImporter::LogError("expected IfcHalfSpaceSolid as second clipping operand"); - return; - } - - const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>(); - if(!plane) { - IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid"); - return; - } - - if(const IfcBooleanResult* const op0 = clip->FirstOperand->ResolveSelectPtr<IfcBooleanResult>(conv.db)) { - ProcessBoolean(*op0,meshout,conv); - } - else if (const IfcSweptAreaSolid* const swept = clip->FirstOperand->ResolveSelectPtr<IfcSweptAreaSolid>(conv.db)) { - ProcessSweptAreaSolid(*swept,meshout,conv); - } - else { - IFCImporter::LogError("expected IfcSweptAreaSolid or IfcBooleanResult as first clipping operand"); - return; - } - - // extract plane base position vector and normal vector - IfcVector3 p,n(0.f,0.f,1.f); - if (plane->Position->Axis) { - ConvertDirection(n,plane->Position->Axis.Get()); - } - ConvertCartesianPoint(p,plane->Position->Location); - - if(!IsTrue(hs->AgreementFlag)) { - n *= -1.f; - } - - // clip the current contents of `meshout` against the plane we obtained from the second operand - const std::vector<IfcVector3>& in = meshout.verts; - std::vector<IfcVector3>& outvert = result.verts; - std::vector<unsigned int>::const_iterator begin=meshout.vertcnt.begin(), end=meshout.vertcnt.end(), iit; - - outvert.reserve(in.size()); - result.vertcnt.reserve(meshout.vertcnt.size()); - - unsigned int vidx = 0; - for(iit = begin; iit != end; vidx += *iit++) { - - unsigned int newcount = 0; - for(unsigned int i = 0; i < *iit; ++i) { - const IfcVector3& e0 = in[vidx+i], e1 = in[vidx+(i+1)%*iit]; - - // does the next segment intersect the plane? - IfcVector3 isectpos; - const Intersect isect = IntersectSegmentPlane(p,n,e0,e1,isectpos); - if (isect == Intersect_No || isect == Intersect_LiesOnPlane) { - if ( (e0-p).Normalize()*n > 0 ) { - outvert.push_back(e0); - ++newcount; - } - } - else if (isect == Intersect_Yes) { - if ( (e0-p).Normalize()*n > 0 ) { - // e0 is on the right side, so keep it - outvert.push_back(e0); - outvert.push_back(isectpos); - newcount += 2; - } - else { - // e0 is on the wrong side, so drop it and keep e1 instead - outvert.push_back(isectpos); - ++newcount; - } - } - } - - if (!newcount) { - continue; - } - - IfcVector3 vmin,vmax; - ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax); - - // filter our IfcFloat points - those may happen if a point lies - // directly on the intersection line. However, due to IfcFloat - // precision a bitwise comparison is not feasible to detect - // this case. - const IfcFloat epsilon = (vmax-vmin).SquareLength() / 1e6f; - FuzzyVectorCompare fz(epsilon); - - std::vector<IfcVector3>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz ); - if (e != outvert.end()) { - newcount -= static_cast<unsigned int>(std::distance(e,outvert.end())); - outvert.erase(e,outvert.end()); - } - if (fz(*( outvert.end()-newcount),outvert.back())) { - outvert.pop_back(); - --newcount; - } - if(newcount > 2) { - result.vertcnt.push_back(newcount); - } - else while(newcount-->0)result.verts.pop_back(); - - } - IFCImporter::LogDebug("generating CSG geometry by plane clipping (IfcBooleanClippingResult)"); - } - else { - IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is " + boolean.GetClassName()); - } -} - - - -// ------------------------------------------------------------------------------------------------ -bool ProcessGeometricItem(const IfcRepresentationItem& geo, std::vector<unsigned int>& mesh_indices, ConversionData& conv) -{ - TempMesh meshtmp; + bool fix_orientation = true; + boost::shared_ptr< TempMesh > meshtmp = boost::make_shared<TempMesh>(); if(const IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<IfcShellBasedSurfaceModel>()) { BOOST_FOREACH(boost::shared_ptr<const IfcShell> shell,shellmod->SbsmBoundary) { try { const EXPRESS::ENTITY& e = shell->To<ENTITY>(); const IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<IfcConnectedFaceSet>(); - ProcessConnectedFaceSet(fs,meshtmp,conv); + ProcessConnectedFaceSet(fs,*meshtmp.get(),conv); } catch(std::bad_cast&) { IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet"); @@ -1718,21 +718,25 @@ bool ProcessGeometricItem(const IfcRepresentationItem& geo, std::vector<unsigned } } else if(const IfcConnectedFaceSet* fset = geo.ToPtr<IfcConnectedFaceSet>()) { - ProcessConnectedFaceSet(*fset,meshtmp,conv); + ProcessConnectedFaceSet(*fset,*meshtmp.get(),conv); } else if(const IfcSweptAreaSolid* swept = geo.ToPtr<IfcSweptAreaSolid>()) { - ProcessSweptAreaSolid(*swept,meshtmp,conv); + ProcessSweptAreaSolid(*swept,*meshtmp.get(),conv); + } + else if(const IfcSweptDiskSolid* disk = geo.ToPtr<IfcSweptDiskSolid>()) { + ProcessSweptDiskSolid(*disk,*meshtmp.get(),conv); + fix_orientation = false; } else if(const IfcManifoldSolidBrep* brep = geo.ToPtr<IfcManifoldSolidBrep>()) { - ProcessConnectedFaceSet(brep->Outer,meshtmp,conv); + ProcessConnectedFaceSet(brep->Outer,*meshtmp.get(),conv); } else if(const IfcFaceBasedSurfaceModel* surf = geo.ToPtr<IfcFaceBasedSurfaceModel>()) { BOOST_FOREACH(const IfcConnectedFaceSet& fc, surf->FbsmFaces) { - ProcessConnectedFaceSet(fc,meshtmp,conv); + ProcessConnectedFaceSet(fc,*meshtmp.get(),conv); } } else if(const IfcBooleanResult* boolean = geo.ToPtr<IfcBooleanResult>()) { - ProcessBoolean(*boolean,meshtmp,conv); + ProcessBoolean(*boolean,*meshtmp.get(),conv); } else if(geo.ToPtr<IfcBoundingBox>()) { // silently skip over bounding boxes @@ -1743,10 +747,35 @@ bool ProcessGeometricItem(const IfcRepresentationItem& geo, std::vector<unsigned return false; } - meshtmp.RemoveAdjacentDuplicates(); - FixupFaceOrientation(meshtmp); + // Do we just collect openings for a parent element (i.e. a wall)? + // In such a case, we generate the polygonal mesh as usual, + // but attach it to a TempOpening instance which will later be applied + // to the wall it pertains to. + + // Note: swep area solids are added in ProcessExtrudedAreaSolid(), + // which returns an empty mesh. + if(conv.collect_openings) { + if (!meshtmp->IsEmpty()) { + conv.collect_openings->push_back(TempOpening(geo.ToPtr<IfcSolidModel>(), + IfcVector3(0,0,0), + meshtmp, + boost::shared_ptr<TempMesh>())); + } + return true; + } + + if (meshtmp->IsEmpty()) { + return false; + } + + meshtmp->RemoveAdjacentDuplicates(); + meshtmp->RemoveDegenerates(); + + if(fix_orientation) { + meshtmp->FixupFaceOrientation(); + } - aiMesh* const mesh = meshtmp.ToMesh(); + aiMesh* const mesh = meshtmp->ToMesh(); if(mesh) { mesh->mMaterialIndex = ProcessMaterials(geo,conv); mesh_indices.push_back(conv.meshes.size()); @@ -1757,7 +786,8 @@ bool ProcessGeometricItem(const IfcRepresentationItem& geo, std::vector<unsigned } // ------------------------------------------------------------------------------------------------ -void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/) +void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd, + ConversionData& /*conv*/) { if (!mesh_indices.empty()) { @@ -1776,7 +806,9 @@ void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,Conver } // ------------------------------------------------------------------------------------------------ -bool TryQueryMeshCache(const IfcRepresentationItem& item, std::vector<unsigned int>& mesh_indices, ConversionData& conv) +bool TryQueryMeshCache(const IfcRepresentationItem& item, + std::vector<unsigned int>& mesh_indices, + ConversionData& conv) { ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(&item); if (it != conv.cached_meshes.end()) { @@ -1787,13 +819,17 @@ bool TryQueryMeshCache(const IfcRepresentationItem& item, std::vector<unsigned i } // ------------------------------------------------------------------------------------------------ -void PopulateMeshCache(const IfcRepresentationItem& item, const std::vector<unsigned int>& mesh_indices, ConversionData& conv) +void PopulateMeshCache(const IfcRepresentationItem& item, + const std::vector<unsigned int>& mesh_indices, + ConversionData& conv) { conv.cached_meshes[&item] = mesh_indices; } // ------------------------------------------------------------------------------------------------ -bool ProcessRepresentationItem(const IfcRepresentationItem& item, std::vector<unsigned int>& mesh_indices, ConversionData& conv) +bool ProcessRepresentationItem(const IfcRepresentationItem& item, + std::vector<unsigned int>& mesh_indices, + ConversionData& conv) { if (!TryQueryMeshCache(item,mesh_indices,conv)) { if(ProcessGeometricItem(item,mesh_indices,conv)) { @@ -1806,9 +842,6 @@ bool ProcessRepresentationItem(const IfcRepresentationItem& item, std::vector<un return true; } -#undef to_int64 -#undef from_int64 -#undef from_int64_f } // ! IFC } // ! Assimp diff --git a/src/3rdparty/assimp/code/IFCLoader.cpp b/src/3rdparty/assimp/code/IFCLoader.cpp index 381068751..9963ce70a 100644 --- a/src/3rdparty/assimp/code/IFCLoader.cpp +++ b/src/3rdparty/assimp/code/IFCLoader.cpp @@ -48,6 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <iterator> #include <boost/tuple/tuple.hpp> +#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC +# include "../contrib/unzip/unzip.h" +#endif #include "IFCLoader.h" #include "STEPFileReader.h" @@ -103,7 +106,7 @@ static const aiImporterDesc desc = { 0, 0, 0, - "ifc" + "ifc ifczip" }; @@ -123,7 +126,7 @@ IFCImporter::~IFCImporter() bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { const std::string& extension = GetExtension(pFile); - if (extension == "ifc") { + if (extension == "ifc" || extension == "ifczip") { return true; } @@ -168,6 +171,66 @@ void IFCImporter::InternReadFile( const std::string& pFile, ThrowException("Could not open file for reading"); } + + // if this is a ifczip file, decompress its contents first + if(GetExtension(pFile) == "ifczip") { +#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC + unzFile zip = unzOpen( pFile.c_str() ); + if(zip == NULL) { + ThrowException("Could not open ifczip file for reading, unzip failed"); + } + + // chop 'zip' postfix + std::string fileName = pFile.substr(0,pFile.length() - 3); + + std::string::size_type s = pFile.find_last_of('\\'); + if(s == std::string::npos) { + s = pFile.find_last_of('/'); + } + if(s != std::string::npos) { + fileName = fileName.substr(s+1); + } + + // search file (same name as the IFCZIP except for the file extension) and place file pointer there + if(UNZ_OK == unzGoToFirstFile(zip)) { + do { + // get file size, etc. + unz_file_info fileInfo; + char filename[256]; + unzGetCurrentFileInfo( zip , &fileInfo, filename, sizeof(filename), 0, 0, 0, 0 ); + if (GetExtension(filename) != "ifc") { + continue; + } + uint8_t* buff = new uint8_t[fileInfo.uncompressed_size]; + LogInfo("Decompressing IFCZIP file"); + unzOpenCurrentFile( zip ); + const int ret = unzReadCurrentFile( zip, buff, fileInfo.uncompressed_size); + size_t filesize = fileInfo.uncompressed_size; + if ( ret < 0 || size_t(ret) != filesize ) + { + delete[] buff; + ThrowException("Failed to decompress IFC ZIP file"); + } + unzCloseCurrentFile( zip ); + stream.reset(new MemoryIOStream(buff,fileInfo.uncompressed_size,true)); + break; + + if (unzGoToNextFile(zip) == UNZ_END_OF_LIST_OF_FILE) { + ThrowException("Found no IFC file member in IFCZIP file (1)"); + } + + } while(true); + } + else { + ThrowException("Found no IFC file member in IFCZIP file (2)"); + } + + unzClose(zip); +#else + ThrowException("Could not open ifczip file for reading, assimp was built without ifczip support"); +#endif + } + boost::scoped_ptr<STEP::DB> db(STEP::ReadFileHeader(stream)); const STEP::HeaderInfo& head = static_cast<const STEP::DB&>(*db).GetHeader(); @@ -196,12 +259,11 @@ void IFCImporter::InternReadFile( const std::string& pFile, // tell the reader for which types we need to simulate STEPs reverse indices static const char* const inverse_indices_to_track[] = { - "ifcrelcontainedinspatialstructure", "ifcrelaggregates", "ifcrelvoidselement", "ifcstyleditem" + "ifcrelcontainedinspatialstructure", "ifcrelaggregates", "ifcrelvoidselement", "ifcreldefinesbyproperties", "ifcpropertyset", "ifcstyleditem" }; // feed the IFC schema into the reader and pre-parse all lines STEP::ReadFile(*db, schema, types_to_track, inverse_indices_to_track); - const STEP::LazyObject* proj = db->GetObject("ifcproject"); if (!proj) { ThrowException("missing IfcProject entity"); @@ -217,9 +279,9 @@ void IFCImporter::InternReadFile( const std::string& pFile, // in a build with no entities disabled. See // scripts/IFCImporter/CPPGenerator.py // for more information. -#ifdef ASSIMP_IFC_TEST - db->EvaluateAll(); -#endif + #ifdef ASSIMP_IFC_TEST + db->EvaluateAll(); + #endif // do final data copying if (conv.meshes.size()) { @@ -369,7 +431,7 @@ void GetAbsTransform(aiMatrix4x4& out, const aiNode* nd, ConversionData& conv) bool ProcessMappedItem(const IfcMappedItem& mapped, aiNode* nd_src, std::vector< aiNode* >& subnodes_src, ConversionData& conv) { // insert a custom node here, the cartesian transform operator is simply a conventional transformation matrix - std::unique_ptr<aiNode> nd(new aiNode()); + std::auto_ptr<aiNode> nd(new aiNode()); nd->mName.Set("IfcMappedItem"); // handle the Cartesian operator @@ -458,7 +520,7 @@ struct RateRepresentationPredicate { return -3; } - // give strong preference to extruded geometry + // give strong preference to extruded geometry. if (r == "SweptSolid") { return -10; } @@ -495,21 +557,16 @@ void ProcessProductRepresentation(const IfcProduct& el, aiNode* nd, std::vector< if(!el.Representation) { return; } - - std::vector<unsigned int> meshes; - // we want only one representation type, so bring them in a suitable order (i.e try those // that look as if we could read them quickly at first). This way of reading // representation is relatively generic and allows the concrete implementations // for the different representation types to make some sensible choices what // to load and what not to load. const STEP::ListOf< STEP::Lazy< IfcRepresentation >, 1, 0 >& src = el.Representation.Get()->Representations; - std::vector<const IfcRepresentation*> repr_ordered(src.size()); std::copy(src.begin(),src.end(),repr_ordered.begin()); std::sort(repr_ordered.begin(),repr_ordered.end(),RateRepresentationPredicate()); - BOOST_FOREACH(const IfcRepresentation* repr, repr_ordered) { bool res = false; BOOST_FOREACH(const IfcRepresentationItem& item, repr->Items) { @@ -525,10 +582,89 @@ void ProcessProductRepresentation(const IfcProduct& el, aiNode* nd, std::vector< break; } } - AssignAddedMeshes(meshes,nd,conv); } +typedef std::map<std::string, std::string> Metadata; + +// ------------------------------------------------------------------------------------------------ +void ProcessMetadata(const ListOf< Lazy< IfcProperty >, 1, 0 >& set, ConversionData& conv, Metadata& properties, + const std::string& prefix = "", + unsigned int nest = 0) +{ + BOOST_FOREACH(const IfcProperty& property, set) { + const std::string& key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name; + if (const IfcPropertySingleValue* const singleValue = property.ToPtr<IfcPropertySingleValue>()) { + if (singleValue->NominalValue) { + if (const EXPRESS::STRING* str = singleValue->NominalValue.Get()->ToPtr<EXPRESS::STRING>()) { + std::string value = static_cast<std::string>(*str); + properties[key]=value; + } + else if (const EXPRESS::REAL* val = singleValue->NominalValue.Get()->ToPtr<EXPRESS::REAL>()) { + float value = static_cast<float>(*val); + std::stringstream s; + s << value; + properties[key]=s.str(); + } + else if (const EXPRESS::INTEGER* val = singleValue->NominalValue.Get()->ToPtr<EXPRESS::INTEGER>()) { + int64_t value = static_cast<int64_t>(*val); + std::stringstream s; + s << value; + properties[key]=s.str(); + } + } + } + else if (const IfcPropertyListValue* const listValue = property.ToPtr<IfcPropertyListValue>()) { + std::stringstream ss; + ss << "["; + unsigned index=0; + BOOST_FOREACH(const IfcValue::Out& v, listValue->ListValues) { + if (!v) continue; + if (const EXPRESS::STRING* str = v->ToPtr<EXPRESS::STRING>()) { + std::string value = static_cast<std::string>(*str); + ss << "'" << value << "'"; + } + else if (const EXPRESS::REAL* val = v->ToPtr<EXPRESS::REAL>()) { + float value = static_cast<float>(*val); + ss << value; + } + else if (const EXPRESS::INTEGER* val = v->ToPtr<EXPRESS::INTEGER>()) { + int64_t value = static_cast<int64_t>(*val); + ss << value; + } + if (index+1<listValue->ListValues.size()) { + ss << ","; + } + index++; + } + ss << "]"; + properties[key]=ss.str(); + } + else if (const IfcComplexProperty* const complexProp = property.ToPtr<IfcComplexProperty>()) { + if(nest > 2) { // mostly arbitrary limit to prevent stack overflow vulnerabilities + IFCImporter::LogError("maximum nesting level for IfcComplexProperty reached, skipping this property."); + } + else { + ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1); + } + } + else { + properties[key]=""; + } + } +} + + +// ------------------------------------------------------------------------------------------------ +void ProcessMetadata(uint64_t relDefinesByPropertiesID, ConversionData& conv, Metadata& properties) +{ + if (const IfcRelDefinesByProperties* const pset = conv.db.GetObject(relDefinesByPropertiesID)->ToPtr<IfcRelDefinesByProperties>()) { + if (const IfcPropertySet* const set = conv.db.GetObject(pset->RelatingPropertyDefinition->GetID())->ToPtr<IfcPropertySet>()) { + ProcessMetadata(set->HasProperties, conv, properties); + } + } +} + // ------------------------------------------------------------------------------------------------ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, ConversionData& conv, std::vector<TempOpening>* collect_openings = NULL) { @@ -550,10 +686,42 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion } // add an output node for this spatial structure - std::unique_ptr<aiNode> nd(new aiNode()); - nd->mName.Set(el.GetClassName()+"_"+(el.Name?el.Name:el.GlobalId)); + std::auto_ptr<aiNode> nd(new aiNode()); + nd->mName.Set(el.GetClassName()+"_"+(el.Name?el.Name.Get():"Unnamed")+"_"+el.GlobalId); nd->mParent = parent; + conv.already_processed.insert(el.GetID()); + + // check for node metadata + STEP::DB::RefMapRange children = refs.equal_range(el.GetID()); + if (children.first!=refs.end()) { + Metadata properties; + if (children.first==children.second) { + // handles single property set + ProcessMetadata((*children.first).second, conv, properties); + } + else { + // handles multiple property sets (currently all property sets are merged, + // which may not be the best solution in the long run) + for (STEP::DB::RefMap::const_iterator it=children.first; it!=children.second; ++it) { + ProcessMetadata((*it).second, conv, properties); + } + } + + if (!properties.empty()) { + aiMetadata* data = new aiMetadata(); + data->mNumProperties = properties.size(); + data->mKeys = new aiString[data->mNumProperties](); + data->mValues = new aiMetadataEntry[data->mNumProperties](); + + unsigned int index = 0; + BOOST_FOREACH(const Metadata::value_type& kv, properties) + data->Set(index++, kv.first, aiString(kv.second)); + + nd->mMetaData = data; + } + } + if(el.ObjectPlacement) { ResolveObjectPlacement(nd->mTransformation,el.ObjectPlacement.Get(),conv); } @@ -572,15 +740,24 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion STEP::DB::RefMapRange range = refs.equal_range(el.GetID()); for(STEP::DB::RefMapRange range2 = range; range2.first != range.second; ++range2.first) { + // skip over meshes that have already been processed before. This is strictly necessary + // because the reverse indices also include references contained in argument lists and + // therefore every element has a back-reference hold by its parent. + if (conv.already_processed.find((*range2.first).second) != conv.already_processed.end()) { + continue; + } const STEP::LazyObject& obj = conv.db.MustGetObject((*range2.first).second); // handle regularly-contained elements if(const IfcRelContainedInSpatialStructure* const cont = obj->ToPtr<IfcRelContainedInSpatialStructure>()) { + if(cont->RelatingStructure->GetID() != el.GetID()) { + continue; + } BOOST_FOREACH(const IfcProduct& pro, cont->RelatedElements) { if(const IfcOpeningElement* const open = pro.ToPtr<IfcOpeningElement>()) { // IfcOpeningElement is handled below. Sadly we can't use it here as is: - // The docs say that opening elements are USUALLY attached to building storeys - // but we want them for the building elements to which they belong to. + // The docs say that opening elements are USUALLY attached to building storey, + // but we want them for the building elements to which they belong. continue; } @@ -596,7 +773,7 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion const IfcFeatureElementSubtraction& open = fills->RelatedOpeningElement; // move opening elements to a separate node since they are semantically different than elements that are just 'contained' - std::unique_ptr<aiNode> nd_aggr(new aiNode()); + std::auto_ptr<aiNode> nd_aggr(new aiNode()); nd_aggr->mName.Set("$RelVoidsElement"); nd_aggr->mParent = nd.get(); @@ -631,10 +808,17 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion } for(;range.first != range.second; ++range.first) { + // see note in loop above + if (conv.already_processed.find((*range.first).second) != conv.already_processed.end()) { + continue; + } if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr<IfcRelAggregates>()) { + if(aggr->RelatingObject->GetID() != el.GetID()) { + continue; + } // move aggregate elements to a separate node since they are semantically different than elements that are just 'contained' - std::unique_ptr<aiNode> nd_aggr(new aiNode()); + std::auto_ptr<aiNode> nd_aggr(new aiNode()); nd_aggr->mName.Set("$RelAggregates"); nd_aggr->mParent = nd.get(); @@ -677,6 +861,8 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion throw; } + ai_assert(conv.already_processed.find(el.GetID()) != conv.already_processed.end()); + conv.already_processed.erase(conv.already_processed.find(el.GetID())); return nd.release(); } diff --git a/src/3rdparty/assimp/code/IFCMaterial.cpp b/src/3rdparty/assimp/code/IFCMaterial.cpp index c8d115d44..4708cdd84 100644 --- a/src/3rdparty/assimp/code/IFCMaterial.cpp +++ b/src/3rdparty/assimp/code/IFCMaterial.cpp @@ -123,10 +123,10 @@ void FillMaterial(aiMaterial* mat,const IFC::IfcSurfaceStyle* surf,ConversionDat } } } - } - else if (/*const IFC::IfcSurfaceStyleWithTextures* tex =*/ sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleWithTextures>(conv.db)) { + } /* + else if (const IFC::IfcSurfaceStyleWithTextures* tex = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleWithTextures>(conv.db)) { // XXX - } + } */ } } @@ -159,7 +159,7 @@ unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, Conversion IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side); } - std::unique_ptr<aiMaterial> mat(new aiMaterial()); + std::auto_ptr<aiMaterial> mat(new aiMaterial()); FillMaterial(mat.get(),surf,conv); diff --git a/src/3rdparty/assimp/code/IFCOpenings.cpp b/src/3rdparty/assimp/code/IFCOpenings.cpp new file mode 100644 index 000000000..c26574cc3 --- /dev/null +++ b/src/3rdparty/assimp/code/IFCOpenings.cpp @@ -0,0 +1,1744 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2010, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file IFCOpenings.cpp + * @brief Implements a subset of Ifc CSG operations for pouring + * holes for windows and doors into walls. + */ + +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER +#include "IFCUtil.h" +#include "PolyTools.h" +#include "ProcessHelper.h" + +#include "../contrib/poly2tri/poly2tri/poly2tri.h" +#include "../contrib/clipper/clipper.hpp" + +#include <iterator> + +namespace Assimp { + namespace IFC { + + using ClipperLib::ulong64; + // XXX use full -+ range ... + const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var + + //#define to_int64(p) (static_cast<ulong64>( std::max( 0., std::min( static_cast<IfcFloat>((p)), 1.) ) * max_ulong64 )) +#define to_int64(p) (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 )) +#define from_int64(p) (static_cast<IfcFloat>((p)) / max_ulong64) +#define one_vec (IfcVector2(static_cast<IfcFloat>(1.0),static_cast<IfcFloat>(1.0))) + + + // fallback method to generate wall openings + bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, + TempMesh& curmesh); + + +typedef std::pair< IfcVector2, IfcVector2 > BoundingBox; +typedef std::map<IfcVector2,size_t,XYSorter> XYSortedField; + + +// ------------------------------------------------------------------------------------------------ +void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField& field, + const std::vector< BoundingBox >& bbs, + std::vector<IfcVector2>& out) +{ + if (!(pmin.x-pmax.x) || !(pmin.y-pmax.y)) { + return; + } + + IfcFloat xs = 1e10, xe = 1e10; + bool found = false; + + // Search along the x-axis until we find an opening + XYSortedField::iterator start = field.begin(); + for(; start != field.end(); ++start) { + const BoundingBox& bb = bbs[(*start).second]; + if(bb.first.x >= pmax.x) { + break; + } + + if (bb.second.x > pmin.x && bb.second.y > pmin.y && bb.first.y < pmax.y) { + xs = bb.first.x; + xe = bb.second.x; + found = true; + break; + } + } + + if (!found) { + // the rectangle [pmin,pend] is opaque, fill it + out.push_back(pmin); + out.push_back(IfcVector2(pmin.x,pmax.y)); + out.push_back(pmax); + out.push_back(IfcVector2(pmax.x,pmin.y)); + return; + } + + xs = std::max(pmin.x,xs); + xe = std::min(pmax.x,xe); + + // see if there's an offset to fill at the top of our quad + if (xs - pmin.x) { + out.push_back(pmin); + out.push_back(IfcVector2(pmin.x,pmax.y)); + out.push_back(IfcVector2(xs,pmax.y)); + out.push_back(IfcVector2(xs,pmin.y)); + } + + // search along the y-axis for all openings that overlap xs and our quad + IfcFloat ylast = pmin.y; + found = false; + for(; start != field.end(); ++start) { + const BoundingBox& bb = bbs[(*start).second]; + if (bb.first.x > xs || bb.first.y >= pmax.y) { + break; + } + + if (bb.second.y > ylast) { + + found = true; + const IfcFloat ys = std::max(bb.first.y,pmin.y), ye = std::min(bb.second.y,pmax.y); + if (ys - ylast > 0.0f) { + QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,ys) ,field,bbs,out); + } + + // the following are the window vertices + + /*wnd.push_back(IfcVector2(xs,ys)); + wnd.push_back(IfcVector2(xs,ye)); + wnd.push_back(IfcVector2(xe,ye)); + wnd.push_back(IfcVector2(xe,ys));*/ + ylast = ye; + } + } + if (!found) { + // the rectangle [pmin,pend] is opaque, fill it + out.push_back(IfcVector2(xs,pmin.y)); + out.push_back(IfcVector2(xs,pmax.y)); + out.push_back(IfcVector2(xe,pmax.y)); + out.push_back(IfcVector2(xe,pmin.y)); + return; + } + if (ylast < pmax.y) { + QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,pmax.y) ,field,bbs,out); + } + + // now for the whole rest + if (pmax.x-xe) { + QuadrifyPart(IfcVector2(xe,pmin.y), pmax ,field,bbs,out); + } +} + +typedef std::vector<IfcVector2> Contour; +typedef std::vector<bool> SkipList; // should probably use int for performance reasons + +struct ProjectedWindowContour +{ + Contour contour; + BoundingBox bb; + SkipList skiplist; + bool is_rectangular; + + + ProjectedWindowContour(const Contour& contour, const BoundingBox& bb, bool is_rectangular) + : contour(contour) + , bb(bb) + , is_rectangular(is_rectangular) + {} + + + bool IsInvalid() const { + return contour.empty(); + } + + void FlagInvalid() { + contour.clear(); + } + + void PrepareSkiplist() { + skiplist.resize(contour.size(),false); + } +}; + +typedef std::vector< ProjectedWindowContour > ContourVector; + +// ------------------------------------------------------------------------------------------------ +bool BoundingBoxesOverlapping( const BoundingBox &ibb, const BoundingBox &bb ) +{ + // count the '=' case as non-overlapping but as adjacent to each other + return ibb.first.x < bb.second.x && ibb.second.x > bb.first.x && + ibb.first.y < bb.second.y && ibb.second.y > bb.first.y; +} + +// ------------------------------------------------------------------------------------------------ +bool IsDuplicateVertex(const IfcVector2& vv, const std::vector<IfcVector2>& temp_contour) +{ + // sanity check for duplicate vertices + BOOST_FOREACH(const IfcVector2& cp, temp_contour) { + if ((cp-vv).SquareLength() < 1e-5f) { + return true; + } + } + return false; +} + +// ------------------------------------------------------------------------------------------------ +void ExtractVerticesFromClipper(const ClipperLib::Polygon& poly, std::vector<IfcVector2>& temp_contour, + bool filter_duplicates = false) +{ + temp_contour.clear(); + BOOST_FOREACH(const ClipperLib::IntPoint& point, poly) { + IfcVector2 vv = IfcVector2( from_int64(point.X), from_int64(point.Y)); + vv = std::max(vv,IfcVector2()); + vv = std::min(vv,one_vec); + + if (!filter_duplicates || !IsDuplicateVertex(vv, temp_contour)) { + temp_contour.push_back(vv); + } + } +} + +// ------------------------------------------------------------------------------------------------ +BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly) +{ + IfcVector2 newbb_min, newbb_max; + MinMaxChooser<IfcVector2>()(newbb_min, newbb_max); + + BOOST_FOREACH(const ClipperLib::IntPoint& point, poly) { + IfcVector2 vv = IfcVector2( from_int64(point.X), from_int64(point.Y)); + + // sanity rounding + vv = std::max(vv,IfcVector2()); + vv = std::min(vv,one_vec); + + newbb_min = std::min(newbb_min,vv); + newbb_max = std::max(newbb_max,vv); + } + return BoundingBox(newbb_min, newbb_max); +} + +// ------------------------------------------------------------------------------------------------ +void InsertWindowContours(const ContourVector& contours, + const std::vector<TempOpening>& openings, + TempMesh& curmesh) +{ + // fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now + for(size_t i = 0; i < contours.size();++i) { + const BoundingBox& bb = contours[i].bb; + const std::vector<IfcVector2>& contour = contours[i].contour; + if(contour.empty()) { + continue; + } + + // check if we need to do it at all - many windows just fit perfectly into their quadratic holes, + // i.e. their contours *are* already their bounding boxes. + if (contour.size() == 4) { + std::set<IfcVector2,XYSorter> verts; + for(size_t n = 0; n < 4; ++n) { + verts.insert(contour[n]); + } + const std::set<IfcVector2,XYSorter>::const_iterator end = verts.end(); + if (verts.find(bb.first)!=end && verts.find(bb.second)!=end + && verts.find(IfcVector2(bb.first.x,bb.second.y))!=end + && verts.find(IfcVector2(bb.second.x,bb.first.y))!=end + ) { + continue; + } + } + + const IfcFloat diag = (bb.first-bb.second).Length(); + const IfcFloat epsilon = diag/1000.f; + + // walk through all contour points and find those that lie on the BB corner + size_t last_hit = -1, very_first_hit = -1; + IfcVector2 edge; + for(size_t n = 0, e=0, size = contour.size();; n=(n+1)%size, ++e) { + + // sanity checking + if (e == size*2) { + IFCImporter::LogError("encountered unexpected topology while generating window contour"); + break; + } + + const IfcVector2& v = contour[n]; + + bool hit = false; + if (fabs(v.x-bb.first.x)<epsilon) { + edge.x = bb.first.x; + hit = true; + } + else if (fabs(v.x-bb.second.x)<epsilon) { + edge.x = bb.second.x; + hit = true; + } + + if (fabs(v.y-bb.first.y)<epsilon) { + edge.y = bb.first.y; + hit = true; + } + else if (fabs(v.y-bb.second.y)<epsilon) { + edge.y = bb.second.y; + hit = true; + } + + if (hit) { + if (last_hit != (size_t)-1) { + + const size_t old = curmesh.verts.size(); + size_t cnt = last_hit > n ? size-(last_hit-n) : n-last_hit; + for(size_t a = last_hit, e = 0; e <= cnt; a=(a+1)%size, ++e) { + // hack: this is to fix cases where opening contours are self-intersecting. + // Clipper doesn't produce such polygons, but as soon as we're back in + // our brave new floating-point world, very small distances are consumed + // by the maximum available precision, leading to self-intersecting + // polygons. This fix makes concave windows fail even worse, but + // anyway, fail is fail. + if ((contour[a] - edge).SquareLength() > diag*diag*0.7) { + continue; + } + curmesh.verts.push_back(IfcVector3(contour[a].x, contour[a].y, 0.0f)); + } + + if (edge != contour[last_hit]) { + + IfcVector2 corner = edge; + + if (fabs(contour[last_hit].x-bb.first.x)<epsilon) { + corner.x = bb.first.x; + } + else if (fabs(contour[last_hit].x-bb.second.x)<epsilon) { + corner.x = bb.second.x; + } + + if (fabs(contour[last_hit].y-bb.first.y)<epsilon) { + corner.y = bb.first.y; + } + else if (fabs(contour[last_hit].y-bb.second.y)<epsilon) { + corner.y = bb.second.y; + } + + curmesh.verts.push_back(IfcVector3(corner.x, corner.y, 0.0f)); + } + else if (cnt == 1) { + // avoid degenerate polygons (also known as lines or points) + curmesh.verts.erase(curmesh.verts.begin()+old,curmesh.verts.end()); + } + + if (const size_t d = curmesh.verts.size()-old) { + curmesh.vertcnt.push_back(d); + std::reverse(curmesh.verts.rbegin(),curmesh.verts.rbegin()+d); + } + if (n == very_first_hit) { + break; + } + } + else { + very_first_hit = n; + } + + last_hit = n; + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +void MergeWindowContours (const std::vector<IfcVector2>& a, + const std::vector<IfcVector2>& b, + ClipperLib::ExPolygons& out) +{ + out.clear(); + + ClipperLib::Clipper clipper; + ClipperLib::Polygon clip; + + BOOST_FOREACH(const IfcVector2& pip, a) { + clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + } + + if (ClipperLib::Orientation(clip)) { + std::reverse(clip.begin(), clip.end()); + } + + clipper.AddPolygon(clip, ClipperLib::ptSubject); + clip.clear(); + + BOOST_FOREACH(const IfcVector2& pip, b) { + clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + } + + if (ClipperLib::Orientation(clip)) { + std::reverse(clip.begin(), clip.end()); + } + + clipper.AddPolygon(clip, ClipperLib::ptSubject); + clipper.Execute(ClipperLib::ctUnion, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero); +} + +// ------------------------------------------------------------------------------------------------ +// Subtract a from b +void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a, + const std::vector<IfcVector2>& b, + ClipperLib::ExPolygons& out) +{ + out.clear(); + + ClipperLib::Clipper clipper; + ClipperLib::Polygon clip; + + BOOST_FOREACH(const IfcVector2& pip, a) { + clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + } + + if (ClipperLib::Orientation(clip)) { + std::reverse(clip.begin(), clip.end()); + } + + clipper.AddPolygon(clip, ClipperLib::ptClip); + clip.clear(); + + BOOST_FOREACH(const IfcVector2& pip, b) { + clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + } + + if (ClipperLib::Orientation(clip)) { + std::reverse(clip.begin(), clip.end()); + } + + clipper.AddPolygon(clip, ClipperLib::ptSubject); + clipper.Execute(ClipperLib::ctDifference, out,ClipperLib::pftNonZero,ClipperLib::pftNonZero); +} + +// ------------------------------------------------------------------------------------------------ +void CleanupWindowContour(ProjectedWindowContour& window) +{ + std::vector<IfcVector2> scratch; + std::vector<IfcVector2>& contour = window.contour; + + ClipperLib::Polygon subject; + ClipperLib::Clipper clipper; + ClipperLib::ExPolygons clipped; + + BOOST_FOREACH(const IfcVector2& pip, contour) { + subject.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + } + + clipper.AddPolygon(subject,ClipperLib::ptSubject); + clipper.Execute(ClipperLib::ctUnion,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero); + + // This should yield only one polygon or something went wrong + if (clipped.size() != 1) { + + // Empty polygon? drop the contour altogether + if(clipped.empty()) { + IFCImporter::LogError("error during polygon clipping, window contour is degenerate"); + window.FlagInvalid(); + return; + } + + // Else: take the first only + IFCImporter::LogError("error during polygon clipping, window contour is not convex"); + } + + ExtractVerticesFromClipper(clipped[0].outer, scratch); + // Assume the bounding box doesn't change during this operation +} + +// ------------------------------------------------------------------------------------------------ +void CleanupWindowContours(ContourVector& contours) +{ + // Use PolyClipper to clean up window contours + try { + BOOST_FOREACH(ProjectedWindowContour& window, contours) { + CleanupWindowContour(window); + } + } + catch (const char* sx) { + IFCImporter::LogError("error during polygon clipping, window shape may be wrong: (Clipper: " + + std::string(sx) + ")"); + } +} + +// ------------------------------------------------------------------------------------------------ +void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh& curmesh) +{ + std::vector<IfcVector3> vold; + std::vector<unsigned int> iold; + + vold.reserve(curmesh.verts.size()); + iold.reserve(curmesh.vertcnt.size()); + + // Fix the outer contour using polyclipper + try { + + ClipperLib::Polygon subject; + ClipperLib::Clipper clipper; + ClipperLib::ExPolygons clipped; + + ClipperLib::Polygon clip; + clip.reserve(contour_flat.size()); + BOOST_FOREACH(const IfcVector2& pip, contour_flat) { + clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + } + + if (!ClipperLib::Orientation(clip)) { + std::reverse(clip.begin(), clip.end()); + } + + // We need to run polyclipper on every single polygon -- we can't run it one all + // of them at once or it would merge them all together which would undo all + // previous steps + subject.reserve(4); + size_t index = 0; + size_t countdown = 0; + BOOST_FOREACH(const IfcVector3& pip, curmesh.verts) { + if (!countdown) { + countdown = curmesh.vertcnt[index++]; + if (!countdown) { + continue; + } + } + subject.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + if (--countdown == 0) { + if (!ClipperLib::Orientation(subject)) { + std::reverse(subject.begin(), subject.end()); + } + + clipper.AddPolygon(subject,ClipperLib::ptSubject); + clipper.AddPolygon(clip,ClipperLib::ptClip); + + clipper.Execute(ClipperLib::ctIntersection,clipped,ClipperLib::pftNonZero,ClipperLib::pftNonZero); + + BOOST_FOREACH(const ClipperLib::ExPolygon& ex, clipped) { + iold.push_back(ex.outer.size()); + BOOST_FOREACH(const ClipperLib::IntPoint& point, ex.outer) { + vold.push_back(IfcVector3( + from_int64(point.X), + from_int64(point.Y), + 0.0f)); + } + } + + subject.clear(); + clipped.clear(); + clipper.Clear(); + } + } + } + catch (const char* sx) { + IFCImporter::LogError("Ifc: error during polygon clipping, wall contour line may be wrong: (Clipper: " + + std::string(sx) + ")"); + + return; + } + + // swap data arrays + std::swap(vold,curmesh.verts); + std::swap(iold,curmesh.vertcnt); +} + +typedef std::vector<TempOpening*> OpeningRefs; +typedef std::vector<OpeningRefs > OpeningRefVector; + +typedef std::vector<std::pair< + ContourVector::const_iterator, + Contour::const_iterator> +> ContourRefVector; + +// ------------------------------------------------------------------------------------------------ +bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb) +{ + // TODO: I'm pretty sure there is a much more compact way to check this + const IfcFloat epsilon = 1e-5f; + return (fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) || + (fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) || + (fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) || + (fabs(bb.first.y - ibb.second.y) < epsilon && ibb.first.x <= bb.second.x && ibb.second.x >= bb.first.x); +} + +// ------------------------------------------------------------------------------------------------ +// Check if m0,m1 intersects n0,n1 assuming same ordering of the points in the line segments +// output the intersection points on n0,n1 +bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1, + const IfcVector2& m0, const IfcVector2& m1, + IfcVector2& out0, IfcVector2& out1) +{ + const IfcVector2& n0_to_n1 = n1 - n0; + + const IfcVector2& n0_to_m0 = m0 - n0; + const IfcVector2& n1_to_m1 = m1 - n1; + + const IfcVector2& n0_to_m1 = m1 - n0; + + const IfcFloat e = 1e-5f; + const IfcFloat smalle = 1e-9f; + + static const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity(); + + if (!(n0_to_m0.SquareLength() < e*e || fabs(n0_to_m0 * n0_to_n1) / (n0_to_m0.Length() * n0_to_n1.Length()) > 1-1e-5 )) { + return false; + } + + if (!(n1_to_m1.SquareLength() < e*e || fabs(n1_to_m1 * n0_to_n1) / (n1_to_m1.Length() * n0_to_n1.Length()) > 1-1e-5 )) { + return false; + } + + IfcFloat s0; + IfcFloat s1; + + // pick the axis with the higher absolute difference so the result + // is more accurate. Since we cannot guarantee that the axis with + // the higher absolute difference is big enough as to avoid + // divisions by zero, the case 0/0 ~ infinity is detected and + // handled separately. + if(fabs(n0_to_n1.x) > fabs(n0_to_n1.y)) { + s0 = n0_to_m0.x / n0_to_n1.x; + s1 = n0_to_m1.x / n0_to_n1.x; + + if (fabs(s0) == inf && fabs(n0_to_m0.x) < smalle) { + s0 = 0.; + } + if (fabs(s1) == inf && fabs(n0_to_m1.x) < smalle) { + s1 = 0.; + } + } + else { + s0 = n0_to_m0.y / n0_to_n1.y; + s1 = n0_to_m1.y / n0_to_n1.y; + + if (fabs(s0) == inf && fabs(n0_to_m0.y) < smalle) { + s0 = 0.; + } + if (fabs(s1) == inf && fabs(n0_to_m1.y) < smalle) { + s1 = 0.; + } + } + + if (s1 < s0) { + std::swap(s1,s0); + } + + s0 = std::max(0.0,s0); + s1 = std::max(0.0,s1); + + s0 = std::min(1.0,s0); + s1 = std::min(1.0,s1); + + if (fabs(s1-s0) < e) { + return false; + } + + out0 = n0 + s0 * n0_to_n1; + out1 = n0 + s1 * n0_to_n1; + + return true; +} + +// ------------------------------------------------------------------------------------------------ +void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours) +{ + const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(1e-8); + const BoundingBox& bb = (*current).bb; + + // What is to be done here is to populate the skip lists for the contour + // and to add necessary padding points when needed. + SkipList& skiplist = (*current).skiplist; + + // First step to find possible adjacent contours is to check for adjacent bounding + // boxes. If the bounding boxes are not adjacent, the contours lines cannot possibly be. + for (ContourVector::const_iterator it = contours.begin(), end = contours.end(); it != end; ++it) { + if ((*it).IsInvalid()) { + continue; + } + + // this left here to make clear we also run on the current contour + // to check for overlapping contour segments (which can happen due + // to projection artifacts). + //if(it == current) { + // continue; + //} + + const bool is_me = it == current; + + const BoundingBox& ibb = (*it).bb; + + // Assumption: the bounding boxes are pairwise disjoint or identical + ai_assert(is_me || !BoundingBoxesOverlapping(bb, ibb)); + + if (is_me || BoundingBoxesAdjacent(bb, ibb)) { + + // Now do a each-against-everyone check for intersecting contour + // lines. This obviously scales terribly, but in typical real + // world Ifc files it will not matter since most windows that + // are adjacent to each others are rectangular anyway. + + Contour& ncontour = (*current).contour; + const Contour& mcontour = (*it).contour; + + for (size_t n = 0; n < ncontour.size(); ++n) { + const IfcVector2& n0 = ncontour[n]; + const IfcVector2& n1 = ncontour[(n+1) % ncontour.size()]; + + for (size_t m = 0, mend = (is_me ? n : mcontour.size()); m < mend; ++m) { + ai_assert(&mcontour != &ncontour || m < n); + + const IfcVector2& m0 = mcontour[m]; + const IfcVector2& m1 = mcontour[(m+1) % mcontour.size()]; + + IfcVector2 isect0, isect1; + if (IntersectingLineSegments(n0,n1, m0, m1, isect0, isect1)) { + + if ((isect0 - n0).SquareLength() > sqlen_epsilon) { + ++n; + + ncontour.insert(ncontour.begin() + n, isect0); + skiplist.insert(skiplist.begin() + n, true); + } + else { + skiplist[n] = true; + } + + if ((isect1 - n1).SquareLength() > sqlen_epsilon) { + ++n; + + ncontour.insert(ncontour.begin() + n, isect1); + skiplist.insert(skiplist.begin() + n, false); + } + } + } + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta) +{ + const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(1e-5); + return fabs(vdelta.x * vdelta.y) < dot_point_epsilon; +} + +// ------------------------------------------------------------------------------------------------ +void FindBorderContours(ContourVector::iterator current) +{ + const IfcFloat border_epsilon_upper = static_cast<IfcFloat>(1-1e-4); + const IfcFloat border_epsilon_lower = static_cast<IfcFloat>(1e-4); + + bool outer_border = false; + bool start_on_outer_border = false; + + SkipList& skiplist = (*current).skiplist; + IfcVector2 last_proj_point; + + const Contour::const_iterator cbegin = (*current).contour.begin(), cend = (*current).contour.end(); + + for (Contour::const_iterator cit = cbegin; cit != cend; ++cit) { + const IfcVector2& proj_point = *cit; + + // Check if this connection is along the outer boundary of the projection + // plane. In such a case we better drop it because such 'edges' should + // not have any geometry to close them (think of door openings). + if (proj_point.x <= border_epsilon_lower || proj_point.x >= border_epsilon_upper || + proj_point.y <= border_epsilon_lower || proj_point.y >= border_epsilon_upper) { + + if (outer_border) { + ai_assert(cit != cbegin); + if (LikelyBorder(proj_point - last_proj_point)) { + skiplist[std::distance(cbegin, cit) - 1] = true; + } + } + else if (cit == cbegin) { + start_on_outer_border = true; + } + + outer_border = true; + } + else { + outer_border = false; + } + + last_proj_point = proj_point; + } + + // handle last segment + if (outer_border && start_on_outer_border) { + const IfcVector2& proj_point = *cbegin; + if (LikelyBorder(proj_point - last_proj_point)) { + skiplist[skiplist.size()-1] = true; + } + } +} + +// ------------------------------------------------------------------------------------------------ +AI_FORCE_INLINE bool LikelyDiagonal(IfcVector2 vdelta) +{ + vdelta.x = fabs(vdelta.x); + vdelta.y = fabs(vdelta.y); + return (fabs(vdelta.x-vdelta.y) < 0.8 * std::max(vdelta.x, vdelta.y)); +} + +// ------------------------------------------------------------------------------------------------ +void FindLikelyCrossingLines(ContourVector::iterator current) +{ + SkipList& skiplist = (*current).skiplist; + IfcVector2 last_proj_point; + + const Contour::const_iterator cbegin = (*current).contour.begin(), cend = (*current).contour.end(); + for (Contour::const_iterator cit = cbegin; cit != cend; ++cit) { + const IfcVector2& proj_point = *cit; + + if (cit != cbegin) { + IfcVector2 vdelta = proj_point - last_proj_point; + if (LikelyDiagonal(vdelta)) { + skiplist[std::distance(cbegin, cit) - 1] = true; + } + } + + last_proj_point = proj_point; + } + + // handle last segment + if (LikelyDiagonal(*cbegin - last_proj_point)) { + skiplist[skiplist.size()-1] = true; + } +} + +// ------------------------------------------------------------------------------------------------ +size_t CloseWindows(ContourVector& contours, + const IfcMatrix4& minv, + OpeningRefVector& contours_to_openings, + TempMesh& curmesh) +{ + size_t closed = 0; + // For all contour points, check if one of the assigned openings does + // already have points assigned to it. In this case, assume this is + // the other side of the wall and generate connections between + // the two holes in order to close the window. + + // All this gets complicated by the fact that contours may pertain to + // multiple openings(due to merging of adjacent or overlapping openings). + // The code is based on the assumption that this happens symmetrically + // on both sides of the wall. If it doesn't (which would be a bug anyway) + // wrong geometry may be generated. + for (ContourVector::iterator it = contours.begin(), end = contours.end(); it != end; ++it) { + if ((*it).IsInvalid()) { + continue; + } + OpeningRefs& refs = contours_to_openings[std::distance(contours.begin(), it)]; + + bool has_other_side = false; + BOOST_FOREACH(const TempOpening* opening, refs) { + if(!opening->wallPoints.empty()) { + has_other_side = true; + break; + } + } + + if (has_other_side) { + + ContourRefVector adjacent_contours; + + // prepare a skiplist for this contour. The skiplist is used to + // eliminate unwanted contour lines for adjacent windows and + // those bordering the outer frame. + (*it).PrepareSkiplist(); + + FindAdjacentContours(it, contours); + FindBorderContours(it); + + // if the window is the result of a finite union or intersection of rectangles, + // there shouldn't be any crossing or diagonal lines in it. Such lines would + // be artifacts caused by numerical inaccuracies or other bugs in polyclipper + // and our own code. Since rectangular openings are by far the most frequent + // case, it is worth filtering for this corner case. + if((*it).is_rectangular) { + FindLikelyCrossingLines(it); + } + + ai_assert((*it).skiplist.size() == (*it).contour.size()); + + SkipList::const_iterator skipbegin = (*it).skiplist.begin(); + + curmesh.verts.reserve(curmesh.verts.size() + (*it).contour.size() * 4); + curmesh.vertcnt.reserve(curmesh.vertcnt.size() + (*it).contour.size()); + + // XXX this algorithm is really a bit inefficient - both in terms + // of constant factor and of asymptotic runtime. + std::vector<bool>::const_iterator skipit = skipbegin; + + IfcVector3 start0; + IfcVector3 start1; + + IfcVector2 last_proj; + //const IfcVector2& first_proj; + + const Contour::const_iterator cbegin = (*it).contour.begin(), cend = (*it).contour.end(); + + bool drop_this_edge = false; + for (Contour::const_iterator cit = cbegin; cit != cend; ++cit, drop_this_edge = *skipit++) { + const IfcVector2& proj_point = *cit; + + // Locate the closest opposite point. This should be a good heuristic to + // connect only the points that are really intended to be connected. + IfcFloat best = static_cast<IfcFloat>(1e10); + IfcVector3 bestv; + + /* debug code to check for unwanted diagonal lines in window contours + if (cit != cbegin) { + const IfcVector2& vdelta = proj_point - last_proj; + if (fabs(vdelta.x-vdelta.y) < 0.5 * std::max(vdelta.x, vdelta.y)) { + //continue; + } + } */ + + const IfcVector3& world_point = minv * IfcVector3(proj_point.x,proj_point.y,0.0f); + + last_proj = proj_point; + + BOOST_FOREACH(const TempOpening* opening, refs) { + BOOST_FOREACH(const IfcVector3& other, opening->wallPoints) { + const IfcFloat sqdist = (world_point - other).SquareLength(); + + if (sqdist < best) { + // avoid self-connections + if(sqdist < 1e-5) { + continue; + } + + bestv = other; + best = sqdist; + } + } + } + + if (drop_this_edge) { + curmesh.verts.pop_back(); + curmesh.verts.pop_back(); + } + else { + curmesh.verts.push_back(cit == cbegin ? world_point : bestv); + curmesh.verts.push_back(cit == cbegin ? bestv : world_point); + + curmesh.vertcnt.push_back(4); + ++closed; + } + + if (cit == cbegin) { + start0 = world_point; + start1 = bestv; + continue; + } + + curmesh.verts.push_back(world_point); + curmesh.verts.push_back(bestv); + + if (cit == cend - 1) { + drop_this_edge = *skipit; + + // Check if the final connection (last to first element) is itself + // a border edge that needs to be dropped. + if (drop_this_edge) { + --closed; + curmesh.vertcnt.pop_back(); + curmesh.verts.pop_back(); + curmesh.verts.pop_back(); + } + else { + curmesh.verts.push_back(start1); + curmesh.verts.push_back(start0); + } + } + } + /* + BOOST_FOREACH(TempOpening* opening, refs) { + //opening->wallPoints.clear(); + }*/ + + } + else { + + const Contour::const_iterator cbegin = (*it).contour.begin(), cend = (*it).contour.end(); + BOOST_FOREACH(TempOpening* opening, refs) { + ai_assert(opening->wallPoints.empty()); + opening->wallPoints.reserve(opening->wallPoints.capacity() + (*it).contour.size()); + for (Contour::const_iterator cit = cbegin; cit != cend; ++cit) { + + const IfcVector2& proj_point = *cit; + opening->wallPoints.push_back(minv * IfcVector3(proj_point.x,proj_point.y,0.0f)); + } + } + } + } + return closed; +} + +// ------------------------------------------------------------------------------------------------ +void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh) +{ + ai_assert(curmesh.IsEmpty()); + + std::vector<IfcVector2> quads; + quads.reserve(bbs.size()*4); + + // sort openings by x and y axis as a preliminiary to the QuadrifyPart() algorithm + XYSortedField field; + for (std::vector<BoundingBox>::const_iterator it = bbs.begin(); it != bbs.end(); ++it) { + if (field.find((*it).first) != field.end()) { + IFCImporter::LogWarn("constraint failure during generation of wall openings, results may be faulty"); + } + field[(*it).first] = std::distance(bbs.begin(),it); + } + + QuadrifyPart(IfcVector2(),one_vec,field,bbs,quads); + ai_assert(!(quads.size() % 4)); + + curmesh.vertcnt.resize(quads.size()/4,4); + curmesh.verts.reserve(quads.size()); + BOOST_FOREACH(const IfcVector2& v2, quads) { + curmesh.verts.push_back(IfcVector3(v2.x, v2.y, static_cast<IfcFloat>(0.0))); + } +} + +// ------------------------------------------------------------------------------------------------ +void Quadrify(const ContourVector& contours, TempMesh& curmesh) +{ + std::vector<BoundingBox> bbs; + bbs.reserve(contours.size()); + + BOOST_FOREACH(const ContourVector::value_type& val, contours) { + bbs.push_back(val.bb); + } + + Quadrify(bbs, curmesh); +} + +// ------------------------------------------------------------------------------------------------ +IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh& in_mesh, + bool &ok, IfcVector3& nor_out) +{ + const std::vector<IfcVector3>& in_verts = in_mesh.verts; + ok = true; + + IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(in_mesh, ok, nor_out)); + if(!ok) { + return IfcMatrix4(); + } +#ifdef ASSIMP_BUILD_DEBUG + const IfcFloat det = m.Determinant(); + ai_assert(fabs(det-1) < 1e-5); +#endif + + IfcFloat zcoord = 0; + out_contour.reserve(in_verts.size()); + + + IfcVector3 vmin, vmax; + MinMaxChooser<IfcVector3>()(vmin, vmax); + + // Project all points into the new coordinate system, collect min/max verts on the way + BOOST_FOREACH(const IfcVector3& x, in_verts) { + const IfcVector3& vv = m * x; + // keep Z offset in the plane coordinate system. Ignoring precision issues + // (which are present, of course), this should be the same value for + // all polygon vertices (assuming the polygon is planar). + + // XXX this should be guarded, but we somehow need to pick a suitable + // epsilon + // if(coord != -1.0f) { + // assert(fabs(coord - vv.z) < 1e-3f); + // } + zcoord += vv.z; + vmin = std::min(vv, vmin); + vmax = std::max(vv, vmax); + + out_contour.push_back(IfcVector2(vv.x,vv.y)); + } + + zcoord /= in_verts.size(); + + // Further improve the projection by mapping the entire working set into + // [0,1] range. This gives us a consistent data range so all epsilons + // used below can be constants. + vmax -= vmin; + BOOST_FOREACH(IfcVector2& vv, out_contour) { + vv.x = (vv.x - vmin.x) / vmax.x; + vv.y = (vv.y - vmin.y) / vmax.y; + + // sanity rounding + vv = std::max(vv,IfcVector2()); + vv = std::min(vv,one_vec); + } + + IfcMatrix4 mult; + mult.a1 = static_cast<IfcFloat>(1.0) / vmax.x; + mult.b2 = static_cast<IfcFloat>(1.0) / vmax.y; + + mult.a4 = -vmin.x * mult.a1; + mult.b4 = -vmin.y * mult.b2; + mult.c4 = -zcoord; + m = mult * m; + + // debug code to verify correctness +#ifdef ASSIMP_BUILD_DEBUG + std::vector<IfcVector2> out_contour2; + BOOST_FOREACH(const IfcVector3& x, in_verts) { + const IfcVector3& vv = m * x; + + out_contour2.push_back(IfcVector2(vv.x,vv.y)); + ai_assert(fabs(vv.z) < vmax.z + 1e-8); + } + + for(size_t i = 0; i < out_contour.size(); ++i) { + ai_assert((out_contour[i]-out_contour2[i]).SquareLength() < 1e-6); + } +#endif + + return m; +} + +// ------------------------------------------------------------------------------------------------ +bool GenerateOpenings(std::vector<TempOpening>& openings, + const std::vector<IfcVector3>& nors, + TempMesh& curmesh, + bool check_intersection, + bool generate_connection_geometry, + const IfcVector3& wall_extrusion_axis) +{ + OpeningRefVector contours_to_openings; + + // Try to derive a solid base plane within the current surface for use as + // working coordinate system. Map all vertices onto this plane and + // rescale them to [0,1] range. This normalization means all further + // epsilons need not be scaled. + bool ok = true; + + std::vector<IfcVector2> contour_flat; + + IfcVector3 nor; + const IfcMatrix4& m = ProjectOntoPlane(contour_flat, curmesh, ok, nor); + if(!ok) { + return false; + } + + // Obtain inverse transform for getting back to world space later on + const IfcMatrix4 minv = IfcMatrix4(m).Inverse(); + + // Compute bounding boxes for all 2D openings in projection space + ContourVector contours; + + std::vector<IfcVector2> temp_contour; + std::vector<IfcVector2> temp_contour2; + + IfcVector3 wall_extrusion_axis_norm = wall_extrusion_axis; + wall_extrusion_axis_norm.Normalize(); + + BOOST_FOREACH(TempOpening& opening,openings) { + + // extrusionDir may be 0,0,0 on case where the opening mesh is not an + // IfcExtrudedAreaSolid but something else (i.e. a brep) + IfcVector3 norm_extrusion_dir = opening.extrusionDir; + if (norm_extrusion_dir.SquareLength() > 1e-10) { + norm_extrusion_dir.Normalize(); + } + else { + norm_extrusion_dir = IfcVector3(); + } + + TempMesh* profile_data = opening.profileMesh.get(); + bool is_2d_source = false; + if (opening.profileMesh2D && norm_extrusion_dir.SquareLength() > 0) { + + if(fabs(norm_extrusion_dir * wall_extrusion_axis_norm) < 0.1) { + // horizontal extrusion + if (fabs(norm_extrusion_dir * nor) > 0.9) { + profile_data = opening.profileMesh2D.get(); + is_2d_source = true; + } + else { + //continue; + } + } + else { + // vertical extrusion + if (fabs(norm_extrusion_dir * nor) > 0.9) { + continue; + } + continue; + } + } + std::vector<IfcVector3> profile_verts = profile_data->verts; + std::vector<unsigned int> profile_vertcnts = profile_data->vertcnt; + if(profile_verts.size() <= 2) { + continue; + } + + // The opening meshes are real 3D meshes so skip over all faces + // clearly facing into the wrong direction. Also, we need to check + // whether the meshes do actually intersect the base surface plane. + // This is done by recording minimum and maximum values for the + // d component of the plane equation for all polys and checking + // against surface d. + + // Use the sign of the dot product of the face normal to the plane + // normal to determine to which side of the difference mesh a + // triangle belongs. Get independent bounding boxes and vertex + // sets for both sides and take the better one (we can't just + // take both - this would likely cause major screwup of vertex + // winding, producing errors as late as in CloseWindows()). + IfcFloat dmin, dmax; + MinMaxChooser<IfcFloat>()(dmin,dmax); + + temp_contour.clear(); + temp_contour2.clear(); + + IfcVector2 vpmin,vpmax; + MinMaxChooser<IfcVector2>()(vpmin,vpmax); + + IfcVector2 vpmin2,vpmax2; + MinMaxChooser<IfcVector2>()(vpmin2,vpmax2); + + for (size_t f = 0, vi_total = 0, fend = profile_vertcnts.size(); f < fend; ++f) { + + bool side_flag = true; + if (!is_2d_source) { + const IfcVector3& face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^ + (profile_verts[vi_total+1] - profile_verts[vi_total])).Normalize(); + + const IfcFloat abs_dot_face_nor = abs(nor * face_nor); + if (abs_dot_face_nor < 0.9) { + vi_total += profile_vertcnts[f]; + continue; + } + + side_flag = nor * face_nor > 0; + } + + for (unsigned int vi = 0, vend = profile_vertcnts[f]; vi < vend; ++vi, ++vi_total) { + const IfcVector3& x = profile_verts[vi_total]; + + const IfcVector3& v = m * x; + IfcVector2 vv(v.x, v.y); + + //if(check_intersection) { + dmin = std::min(dmin, v.z); + dmax = std::max(dmax, v.z); + //} + + // sanity rounding + vv = std::max(vv,IfcVector2()); + vv = std::min(vv,one_vec); + + if(side_flag) { + vpmin = std::min(vpmin,vv); + vpmax = std::max(vpmax,vv); + } + else { + vpmin2 = std::min(vpmin2,vv); + vpmax2 = std::max(vpmax2,vv); + } + + std::vector<IfcVector2>& store = side_flag ? temp_contour : temp_contour2; + + if (!IsDuplicateVertex(vv, store)) { + store.push_back(vv); + } + } + } + + if (temp_contour2.size() > 2) { + ai_assert(!is_2d_source); + const IfcVector2 area = vpmax-vpmin; + const IfcVector2 area2 = vpmax2-vpmin2; + if (temp_contour.size() <= 2 || fabs(area2.x * area2.y) > fabs(area.x * area.y)) { + temp_contour.swap(temp_contour2); + + vpmax = vpmax2; + vpmin = vpmin2; + } + } + if(temp_contour.size() <= 2) { + continue; + } + + // TODO: This epsilon may be too large + const IfcFloat epsilon = fabs(dmax-dmin) * 0.0001; + if (!is_2d_source && check_intersection && (0 < dmin-epsilon || 0 > dmax+epsilon)) { + continue; + } + + BoundingBox bb = BoundingBox(vpmin,vpmax); + + // Skip over very small openings - these are likely projection errors + // (i.e. they don't belong to this side of the wall) + if(fabs(vpmax.x - vpmin.x) * fabs(vpmax.y - vpmin.y) < static_cast<IfcFloat>(1e-10)) { + continue; + } + std::vector<TempOpening*> joined_openings(1, &opening); + + bool is_rectangle = temp_contour.size() == 4; + + // See if this BB intersects or is in close adjacency to any other BB we have so far. + for (ContourVector::iterator it = contours.begin(); it != contours.end(); ) { + const BoundingBox& ibb = (*it).bb; + + if (BoundingBoxesOverlapping(ibb, bb)) { + + if (!(*it).is_rectangular) { + is_rectangle = false; + } + + const std::vector<IfcVector2>& other = (*it).contour; + ClipperLib::ExPolygons poly; + + // First check whether subtracting the old contour (to which ibb belongs) + // from the new contour (to which bb belongs) yields an updated bb which + // no longer overlaps ibb + MakeDisjunctWindowContours(other, temp_contour, poly); + if(poly.size() == 1) { + + const BoundingBox& newbb = GetBoundingBox(poly[0].outer); + if (!BoundingBoxesOverlapping(ibb, newbb )) { + // Good guy bounding box + bb = newbb ; + + ExtractVerticesFromClipper(poly[0].outer, temp_contour, false); + continue; + } + } + + // Take these two overlapping contours and try to merge them. If they + // overlap (which should not happen, but in fact happens-in-the-real- + // world [tm] ), resume using a single contour and a single bounding box. + MergeWindowContours(temp_contour, other, poly); + + if (poly.size() > 1) { + return TryAddOpenings_Poly2Tri(openings, nors, curmesh); + } + else if (poly.size() == 0) { + IFCImporter::LogWarn("ignoring duplicate opening"); + temp_contour.clear(); + break; + } + else { + IFCImporter::LogDebug("merging overlapping openings"); + ExtractVerticesFromClipper(poly[0].outer, temp_contour, false); + + // Generate the union of the bounding boxes + bb.first = std::min(bb.first, ibb.first); + bb.second = std::max(bb.second, ibb.second); + + // Update contour-to-opening tables accordingly + if (generate_connection_geometry) { + std::vector<TempOpening*>& t = contours_to_openings[std::distance(contours.begin(),it)]; + joined_openings.insert(joined_openings.end(), t.begin(), t.end()); + + contours_to_openings.erase(contours_to_openings.begin() + std::distance(contours.begin(),it)); + } + + contours.erase(it); + + // Restart from scratch because the newly formed BB might now + // overlap any other BB which its constituent BBs didn't + // previously overlap. + it = contours.begin(); + continue; + } + } + ++it; + } + + if(!temp_contour.empty()) { + if (generate_connection_geometry) { + contours_to_openings.push_back(std::vector<TempOpening*>( + joined_openings.begin(), + joined_openings.end())); + } + + contours.push_back(ProjectedWindowContour(temp_contour, bb, is_rectangle)); + } + } + + // Check if we still have any openings left - it may well be that this is + // not the cause, for example if all the opening candidates don't intersect + // this surface or point into a direction perpendicular to it. + if (contours.empty()) { + return false; + } + + curmesh.Clear(); + + // Generate a base subdivision into quads to accommodate the given list + // of window bounding boxes. + Quadrify(contours,curmesh); + + // Run a sanity cleanup pass on the window contours to avoid generating + // artifacts during the contour generation phase later on. + CleanupWindowContours(contours); + + // Previously we reduced all windows to rectangular AABBs in projection + // space, now it is time to fill the gaps between the BBs and the real + // window openings. + InsertWindowContours(contours,openings, curmesh); + + // Clip the entire outer contour of our current result against the real + // outer contour of the surface. This is necessary because the result + // of the Quadrify() algorithm is always a square area spanning + // over [0,1]^2 (i.e. entire projection space). + CleanupOuterContour(contour_flat, curmesh); + + // Undo the projection and get back to world (or local object) space + BOOST_FOREACH(IfcVector3& v3, curmesh.verts) { + v3 = minv * v3; + } + + // Generate window caps to connect the symmetric openings on both sides + // of the wall. + if (generate_connection_geometry) { + CloseWindows(contours, minv, contours_to_openings, curmesh); + } + return true; +} + +// ------------------------------------------------------------------------------------------------ +bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, + TempMesh& curmesh) +{ + IFCImporter::LogWarn("forced to use poly2tri fallback method to generate wall openings"); + std::vector<IfcVector3>& out = curmesh.verts; + + bool result = false; + + // Try to derive a solid base plane within the current surface for use as + // working coordinate system. + bool ok; + IfcVector3 nor; + const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh, ok, nor); + if (!ok) { + return false; + } + + const IfcMatrix3 minv = IfcMatrix3(m).Inverse(); + + + IfcFloat coord = -1; + + std::vector<IfcVector2> contour_flat; + contour_flat.reserve(out.size()); + + IfcVector2 vmin, vmax; + MinMaxChooser<IfcVector2>()(vmin, vmax); + + // Move all points into the new coordinate system, collecting min/max verts on the way + BOOST_FOREACH(IfcVector3& x, out) { + const IfcVector3 vv = m * x; + + // keep Z offset in the plane coordinate system. Ignoring precision issues + // (which are present, of course), this should be the same value for + // all polygon vertices (assuming the polygon is planar). + + + // XXX this should be guarded, but we somehow need to pick a suitable + // epsilon + // if(coord != -1.0f) { + // assert(fabs(coord - vv.z) < 1e-3f); + // } + + coord = vv.z; + + vmin = std::min(IfcVector2(vv.x, vv.y), vmin); + vmax = std::max(IfcVector2(vv.x, vv.y), vmax); + + contour_flat.push_back(IfcVector2(vv.x,vv.y)); + } + + // With the current code in DerivePlaneCoordinateSpace, + // vmin,vmax should always be the 0...1 rectangle (+- numeric inaccuracies) + // but here we won't rely on this. + + vmax -= vmin; + + // If this happens then the projection must have been wrong. + assert(vmax.Length()); + + ClipperLib::ExPolygons clipped; + ClipperLib::Polygons holes_union; + + + IfcVector3 wall_extrusion; + bool do_connections = false, first = true; + + try { + + ClipperLib::Clipper clipper_holes; + size_t c = 0; + + BOOST_FOREACH(const TempOpening& t,openings) { + const IfcVector3& outernor = nors[c++]; + const IfcFloat dot = nor * outernor; + if (fabs(dot)<1.f-1e-6f) { + continue; + } + + const std::vector<IfcVector3>& va = t.profileMesh->verts; + if(va.size() <= 2) { + continue; + } + + std::vector<IfcVector2> contour; + + BOOST_FOREACH(const IfcVector3& xx, t.profileMesh->verts) { + IfcVector3 vv = m * xx, vv_extr = m * (xx + t.extrusionDir); + + const bool is_extruded_side = fabs(vv.z - coord) > fabs(vv_extr.z - coord); + if (first) { + first = false; + if (dot > 0.f) { + do_connections = true; + wall_extrusion = t.extrusionDir; + if (is_extruded_side) { + wall_extrusion = - wall_extrusion; + } + } + } + + // XXX should not be necessary - but it is. Why? For precision reasons? + vv = is_extruded_side ? vv_extr : vv; + contour.push_back(IfcVector2(vv.x,vv.y)); + } + + ClipperLib::Polygon hole; + BOOST_FOREACH(IfcVector2& pip, contour) { + pip.x = (pip.x - vmin.x) / vmax.x; + pip.y = (pip.y - vmin.y) / vmax.y; + + hole.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + } + + if (!ClipperLib::Orientation(hole)) { + std::reverse(hole.begin(), hole.end()); + // assert(ClipperLib::Orientation(hole)); + } + + /*ClipperLib::Polygons pol_temp(1), pol_temp2(1); + pol_temp[0] = hole; + + ClipperLib::OffsetPolygons(pol_temp,pol_temp2,5.0); + hole = pol_temp2[0];*/ + + clipper_holes.AddPolygon(hole,ClipperLib::ptSubject); + } + + clipper_holes.Execute(ClipperLib::ctUnion,holes_union, + ClipperLib::pftNonZero, + ClipperLib::pftNonZero); + + if (holes_union.empty()) { + return false; + } + + // Now that we have the big union of all holes, subtract it from the outer contour + // to obtain the final polygon to feed into the triangulator. + { + ClipperLib::Polygon poly; + BOOST_FOREACH(IfcVector2& pip, contour_flat) { + pip.x = (pip.x - vmin.x) / vmax.x; + pip.y = (pip.y - vmin.y) / vmax.y; + + poly.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); + } + + if (ClipperLib::Orientation(poly)) { + std::reverse(poly.begin(), poly.end()); + } + clipper_holes.Clear(); + clipper_holes.AddPolygon(poly,ClipperLib::ptSubject); + + clipper_holes.AddPolygons(holes_union,ClipperLib::ptClip); + clipper_holes.Execute(ClipperLib::ctDifference,clipped, + ClipperLib::pftNonZero, + ClipperLib::pftNonZero); + } + + } + catch (const char* sx) { + IFCImporter::LogError("Ifc: error during polygon clipping, skipping openings for this face: (Clipper: " + + std::string(sx) + ")"); + + return false; + } + + std::vector<IfcVector3> old_verts; + std::vector<unsigned int> old_vertcnt; + + old_verts.swap(curmesh.verts); + old_vertcnt.swap(curmesh.vertcnt); + + + // add connection geometry to close the adjacent 'holes' for the openings + // this should only be done from one side of the wall or the polygons + // would be emitted twice. + if (false && do_connections) { + + std::vector<IfcVector3> tmpvec; + BOOST_FOREACH(ClipperLib::Polygon& opening, holes_union) { + + assert(ClipperLib::Orientation(opening)); + + tmpvec.clear(); + + BOOST_FOREACH(ClipperLib::IntPoint& point, opening) { + + tmpvec.push_back( minv * IfcVector3( + vmin.x + from_int64(point.X) * vmax.x, + vmin.y + from_int64(point.Y) * vmax.y, + coord)); + } + + for(size_t i = 0, size = tmpvec.size(); i < size; ++i) { + const size_t next = (i+1)%size; + + curmesh.vertcnt.push_back(4); + + const IfcVector3& in_world = tmpvec[i]; + const IfcVector3& next_world = tmpvec[next]; + + // Assumptions: no 'partial' openings, wall thickness roughly the same across the wall + curmesh.verts.push_back(in_world); + curmesh.verts.push_back(in_world+wall_extrusion); + curmesh.verts.push_back(next_world+wall_extrusion); + curmesh.verts.push_back(next_world); + } + } + } + + std::vector< std::vector<p2t::Point*> > contours; + BOOST_FOREACH(ClipperLib::ExPolygon& clip, clipped) { + + contours.clear(); + + // Build the outer polygon contour line for feeding into poly2tri + std::vector<p2t::Point*> contour_points; + BOOST_FOREACH(ClipperLib::IntPoint& point, clip.outer) { + contour_points.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) ); + } + + p2t::CDT* cdt ; + try { + // Note: this relies on custom modifications in poly2tri to raise runtime_error's + // instead if assertions. These failures are not debug only, they can actually + // happen in production use if the input data is broken. An assertion would be + // inappropriate. + cdt = new p2t::CDT(contour_points); + } + catch(const std::exception& e) { + IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: " + + std::string(e.what()) + ")"); + continue; + } + + + // Build the poly2tri inner contours for all holes we got from ClipperLib + BOOST_FOREACH(ClipperLib::Polygon& opening, clip.holes) { + + contours.push_back(std::vector<p2t::Point*>()); + std::vector<p2t::Point*>& contour = contours.back(); + + BOOST_FOREACH(ClipperLib::IntPoint& point, opening) { + contour.push_back( new p2t::Point(from_int64(point.X), from_int64(point.Y)) ); + } + + cdt->AddHole(contour); + } + + try { + // Note: See above + cdt->Triangulate(); + } + catch(const std::exception& e) { + IFCImporter::LogError("Ifc: error during polygon triangulation, skipping some openings: (poly2tri: " + + std::string(e.what()) + ")"); + continue; + } + + const std::vector<p2t::Triangle*>& tris = cdt->GetTriangles(); + + // Collect the triangles we just produced + BOOST_FOREACH(p2t::Triangle* tri, tris) { + for(int i = 0; i < 3; ++i) { + + const IfcVector2& v = IfcVector2( + static_cast<IfcFloat>( tri->GetPoint(i)->x ), + static_cast<IfcFloat>( tri->GetPoint(i)->y ) + ); + + assert(v.x <= 1.0 && v.x >= 0.0 && v.y <= 1.0 && v.y >= 0.0); + const IfcVector3 v3 = minv * IfcVector3(vmin.x + v.x * vmax.x, vmin.y + v.y * vmax.y,coord) ; + + curmesh.verts.push_back(v3); + } + curmesh.vertcnt.push_back(3); + } + + result = true; + } + + if (!result) { + // revert -- it's a shame, but better than nothing + curmesh.verts.insert(curmesh.verts.end(),old_verts.begin(), old_verts.end()); + curmesh.vertcnt.insert(curmesh.vertcnt.end(),old_vertcnt.begin(), old_vertcnt.end()); + + IFCImporter::LogError("Ifc: revert, could not generate openings for this wall"); + } + + return result; +} + + + } // ! IFC +} // ! Assimp + +#undef to_int64 +#undef from_int64 +#undef one_vec + +#endif
\ No newline at end of file diff --git a/src/3rdparty/assimp/code/IFCProfile.cpp b/src/3rdparty/assimp/code/IFCProfile.cpp index b2ffa943f..48ccd568e 100644 --- a/src/3rdparty/assimp/code/IFCProfile.cpp +++ b/src/3rdparty/assimp/code/IFCProfile.cpp @@ -101,7 +101,7 @@ void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout } // ------------------------------------------------------------------------------------------------ -void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& /*conv*/) +void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv) { if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) { const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f; @@ -129,6 +129,27 @@ void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout.vertcnt.push_back(segments); } + else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) { + // construct simplified IBeam shape + const IfcFloat offset = (ishape->OverallWidth - ishape->WebThickness) / 2; + const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2; + + meshout.verts.reserve(12); + meshout.verts.push_back(IfcVector3(0,0,0)); + meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness,0)); + meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness,0)); + meshout.verts.push_back(IfcVector3(offset,ishape->FlangeThickness + inner_height,0)); + meshout.verts.push_back(IfcVector3(0,ishape->FlangeThickness + inner_height,0)); + meshout.verts.push_back(IfcVector3(0,ishape->OverallDepth,0)); + meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->OverallDepth,0)); + meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness + inner_height,0)); + meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness + inner_height,0)); + meshout.verts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness,0)); + meshout.verts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness,0)); + meshout.verts.push_back(IfcVector3(ishape->OverallWidth,0,0)); + + meshout.vertcnt.push_back(12); + } else { IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName()); return; diff --git a/src/3rdparty/assimp/code/IFCReaderGen.cpp b/src/3rdparty/assimp/code/IFCReaderGen.cpp index 56d2182fe..c17805172 100644 --- a/src/3rdparty/assimp/code/IFCReaderGen.cpp +++ b/src/3rdparty/assimp/code/IFCReaderGen.cpp @@ -1,8 +1,8 @@ /* -Open Asset Import Library (assimp) +Open Asset Import Library (ASSIMP) ---------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2010, ASSIMP Development Team All rights reserved. Redistribution and use of this software in source and binary forms, @@ -18,10 +18,10 @@ following conditions are met: following disclaimer in the documentation and/or other materials provided with the distribution. -* Neither the name of the assimp team, nor the names of its +* Neither the name of the ASSIMP team, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior - written permission of the assimp team. + written permission of the ASSIMP Development Team. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -52,986 +52,986 @@ namespace { typedef EXPRESS::ConversionSchema::SchemaEntry SchemaEntry; const SchemaEntry schema_raw[] = { - SchemaEntry("ifcsoundpowermeasure",NULL ) -, SchemaEntry("ifcdoorstyleoperationenum",NULL ) -, SchemaEntry("ifcrotationalfrequencymeasure",NULL ) -, SchemaEntry("ifccharacterstyleselect",NULL ) -, SchemaEntry("ifcelectrictimecontroltypeenum",NULL ) -, SchemaEntry("ifcairterminaltypeenum",NULL ) -, SchemaEntry("ifcprojectordertypeenum",NULL ) + SchemaEntry("ifcstairtypeenum",NULL ) +, SchemaEntry("ifcspacetypeenum",NULL ) +, SchemaEntry("ifcwalltypeenum",NULL ) +, SchemaEntry("ifcmonthinyearnumber",NULL ) +, SchemaEntry("ifcheatfluxdensitymeasure",NULL ) +, SchemaEntry("ifckinematicviscositymeasure",NULL ) , SchemaEntry("ifcsequenceenum",NULL ) -, SchemaEntry("ifcspecificheatcapacitymeasure",NULL ) -, SchemaEntry("ifcheatingvaluemeasure",NULL ) -, SchemaEntry("ifcribplatedirectionenum",NULL ) -, SchemaEntry("ifcsensortypeenum",NULL ) -, SchemaEntry("ifcelectricheatertypeenum",NULL ) -, SchemaEntry("ifcobjectiveenum",NULL ) -, SchemaEntry("ifctextstyleselect",NULL ) -, SchemaEntry("ifccolumntypeenum",NULL ) -, SchemaEntry("ifcgasterminaltypeenum",NULL ) +, SchemaEntry("ifcairtoairheatrecoverytypeenum",NULL ) +, SchemaEntry("ifcactorselect",NULL ) +, SchemaEntry("ifctransformertypeenum",NULL ) +, SchemaEntry("ifcunitaryequipmenttypeenum",NULL ) +, SchemaEntry("ifcelectricflowstoragedevicetypeenum",NULL ) +, SchemaEntry("ifcenergysequenceenum",NULL ) +, SchemaEntry("ifcworkcontroltypeenum",NULL ) +, SchemaEntry("ifccurvaturemeasure",NULL ) +, SchemaEntry("ifcparametervalue",NULL ) +, SchemaEntry("ifcappliedvalueselect",NULL ) +, SchemaEntry("ifcwarpingconstantmeasure",NULL ) +, SchemaEntry("ifcarithmeticoperatorenum",NULL ) +, SchemaEntry("ifclinearforcemeasure",NULL ) +, SchemaEntry("ifcwindowpanelpositionenum",NULL ) +, SchemaEntry("ifcflowmetertypeenum",NULL ) +, SchemaEntry("ifcrampflighttypeenum",NULL ) +, SchemaEntry("ifcspecularhighlightselect",NULL ) +, SchemaEntry("ifcactiontypeenum",NULL ) +, SchemaEntry("ifcgeometricprojectionenum",NULL ) +, SchemaEntry("ifctimeseriesdatatypeenum",NULL ) +, SchemaEntry("ifcmagneticfluxmeasure",NULL ) +, SchemaEntry("ifcobjecttypeenum",NULL ) +, SchemaEntry("ifcdataoriginenum",NULL ) , SchemaEntry("ifcmassdensitymeasure",NULL ) +, SchemaEntry("ifclightfixturetypeenum",NULL ) +, SchemaEntry("ifcservicelifetypeenum",NULL ) +, SchemaEntry("ifcelectricvoltagemeasure",NULL ) +, SchemaEntry("ifcheatingvaluemeasure",NULL ) +, SchemaEntry("ifcpresentabletext",NULL ) +, SchemaEntry("ifcaheadorbehind",NULL ) , SchemaEntry("ifcsimplevalue",NULL ) -, SchemaEntry("ifcelectricconductancemeasure",NULL ) -, SchemaEntry("ifcbuildingelementproxytypeenum",NULL ) -, SchemaEntry("ifcjunctionboxtypeenum",NULL ) -, SchemaEntry("ifcmodulusofelasticitymeasure",NULL ) -, SchemaEntry("ifcactionsourcetypeenum",NULL ) -, SchemaEntry("ifcsiunitname",NULL ) -, SchemaEntry("ifcrotationalmassmeasure",NULL ) -, SchemaEntry("ifcmembertypeenum",NULL ) +, SchemaEntry("ifcsensortypeenum",NULL ) +, SchemaEntry("ifcderivedunitenum",NULL ) +, SchemaEntry("ifcsizeselect",NULL ) +, SchemaEntry("ifctransportelementtypeenum",NULL ) +, SchemaEntry("ifcinventorytypeenum",NULL ) , SchemaEntry("ifctextdecoration",NULL ) -, SchemaEntry("ifcpositivelengthmeasure",NULL ) -, SchemaEntry("ifcamountofsubstancemeasure",NULL ) -, SchemaEntry("ifcdoorstyleconstructionenum",NULL ) -, SchemaEntry("ifcangularvelocitymeasure",NULL ) , SchemaEntry("ifcdirectionsenseenum",NULL ) -, SchemaEntry("ifcnullstyle",NULL ) -, SchemaEntry("ifcmonthinyearnumber",NULL ) -, SchemaEntry("ifcrampflighttypeenum",NULL ) -, SchemaEntry("ifcwindowstyleoperationenum",NULL ) -, SchemaEntry("ifccurvaturemeasure",NULL ) -, SchemaEntry("ifcbooleanoperator",NULL ) , SchemaEntry("ifcductfittingtypeenum",NULL ) -, SchemaEntry("ifccurrencyenum",NULL ) -, SchemaEntry("ifcobjecttypeenum",NULL ) -, SchemaEntry("ifcthermalloadtypeenum",NULL ) +, SchemaEntry("ifcdocumentstatusenum",NULL ) +, SchemaEntry("ifcslabtypeenum",NULL ) +, SchemaEntry("ifcdoorstyleconstructionenum",NULL ) +, SchemaEntry("ifcvolumemeasure",NULL ) +, SchemaEntry("ifcinductancemeasure",NULL ) +, SchemaEntry("ifccurtainwalltypeenum",NULL ) +, SchemaEntry("ifcsiunitname",NULL ) +, SchemaEntry("ifcspecularexponent",NULL ) +, SchemaEntry("ifcsoundpressuremeasure",NULL ) +, SchemaEntry("ifcanalysistheorytypeenum",NULL ) +, SchemaEntry("ifcgasterminaltypeenum",NULL ) +, SchemaEntry("ifcyearnumber",NULL ) +, SchemaEntry("ifcmodulusofelasticitymeasure",NULL ) +, SchemaEntry("ifcchangeactionenum",NULL ) +, SchemaEntry("ifcdampertypeenum",NULL ) +, SchemaEntry("ifcevaporatortypeenum",NULL ) , SchemaEntry("ifcionconcentrationmeasure",NULL ) -, SchemaEntry("ifcobjectreferenceselect",NULL ) +, SchemaEntry("ifcductsegmenttypeenum",NULL ) +, SchemaEntry("ifcprotectivedevicetypeenum",NULL ) +, SchemaEntry("ifcabsorbeddosemeasure",NULL ) +, SchemaEntry("ifcmassperlengthmeasure",NULL ) +, SchemaEntry("ifctextfontname",NULL ) +, SchemaEntry("ifcorientationselect",NULL ) +, SchemaEntry("ifcilluminancemeasure",NULL ) +, SchemaEntry("ifcfiresuppressionterminaltypeenum",NULL ) +, SchemaEntry("ifcfontstyle",NULL ) +, SchemaEntry("ifcmomentofinertiameasure",NULL ) +, SchemaEntry("ifcmodulusofsubgradereactionmeasure",NULL ) +, SchemaEntry("ifccomplexnumber",NULL ) +, SchemaEntry("ifchumidifiertypeenum",NULL ) +, SchemaEntry("ifcpresentationstyleselect",NULL ) +, SchemaEntry("ifcthermaltransmittancemeasure",NULL ) +, SchemaEntry("ifcribplatedirectionenum",NULL ) , SchemaEntry("ifcclassificationnotationselect",NULL ) -, SchemaEntry("ifcbsplinecurveform",NULL ) -, SchemaEntry("ifcelementcompositionenum",NULL ) -, SchemaEntry("ifcdraughtingcalloutelement",NULL ) -, SchemaEntry("ifcfillstyleselect",NULL ) -, SchemaEntry("ifcheatfluxdensitymeasure",NULL ) -, SchemaEntry("ifcgeometricprojectionenum",NULL ) -, SchemaEntry("ifcfontvariant",NULL ) -, SchemaEntry("ifcthermalresistancemeasure",NULL ) -, SchemaEntry("ifcreflectancemethodenum",NULL ) -, SchemaEntry("ifcslabtypeenum",NULL ) -, SchemaEntry("ifcpositiveratiomeasure",NULL ) +, SchemaEntry("ifcminuteinhour",NULL ) , SchemaEntry("ifcinternalorexternalenum",NULL ) -, SchemaEntry("ifcdimensionextentusage",NULL ) -, SchemaEntry("ifcpipefittingtypeenum",NULL ) +, SchemaEntry("ifcrotationalfrequencymeasure",NULL ) , SchemaEntry("ifcsanitaryterminaltypeenum",NULL ) -, SchemaEntry("ifcminuteinhour",NULL ) -, SchemaEntry("ifcwalltypeenum",NULL ) -, SchemaEntry("ifcmolecularweightmeasure",NULL ) -, SchemaEntry("ifcunitaryequipmenttypeenum",NULL ) -, SchemaEntry("ifcproceduretypeenum",NULL ) -, SchemaEntry("ifcdistributionchamberelementtypeenum",NULL ) +, SchemaEntry("ifcsymbolstyleselect",NULL ) +, SchemaEntry("ifcelementcompositionenum",NULL ) , SchemaEntry("ifctextpath",NULL ) -, SchemaEntry("ifccostscheduletypeenum",NULL ) -, SchemaEntry("ifcshell",NULL ) -, SchemaEntry("ifclinearmomentmeasure",NULL ) -, SchemaEntry("ifcelectriccurrentmeasure",NULL ) -, SchemaEntry("ifcdaylightsavinghour",NULL ) -, SchemaEntry("ifcnormalisedratiomeasure",NULL ) -, SchemaEntry("ifcfantypeenum",NULL ) -, SchemaEntry("ifccontextdependentmeasure",NULL ) -, SchemaEntry("ifcaheadorbehind",NULL ) -, SchemaEntry("ifcfontstyle",NULL ) -, SchemaEntry("ifccooledbeamtypeenum",NULL ) +, SchemaEntry("ifcpowermeasure",NULL ) , SchemaEntry("ifcsurfacestyleelementselect",NULL ) -, SchemaEntry("ifcyearnumber",NULL ) -, SchemaEntry("ifclabel",NULL ) -, SchemaEntry("ifctimestamp",NULL ) -, SchemaEntry("ifcfiresuppressionterminaltypeenum",NULL ) -, SchemaEntry("ifcdocumentconfidentialityenum",NULL ) -, SchemaEntry("ifccolourorfactor",NULL ) -, SchemaEntry("ifcairterminalboxtypeenum",NULL ) -, SchemaEntry("ifcnumericmeasure",NULL ) -, SchemaEntry("ifcderivedunitenum",NULL ) -, SchemaEntry("ifccurveoredgecurve",NULL ) -, SchemaEntry("ifclightemissionsourceenum",NULL ) -, SchemaEntry("ifckinematicviscositymeasure",NULL ) -, SchemaEntry("ifcboxalignment",NULL ) -, SchemaEntry("ifcdocumentselect",NULL ) -, SchemaEntry("ifccablecarrierfittingtypeenum",NULL ) -, SchemaEntry("ifcpumptypeenum",NULL ) -, SchemaEntry("ifchourinday",NULL ) -, SchemaEntry("ifcprojectorderrecordtypeenum",NULL ) -, SchemaEntry("ifcwindowstyleconstructionenum",NULL ) -, SchemaEntry("ifcpresentationstyleselect",NULL ) -, SchemaEntry("ifccablesegmenttypeenum",NULL ) -, SchemaEntry("ifcwasteterminaltypeenum",NULL ) -, SchemaEntry("ifcisothermalmoisturecapacitymeasure",NULL ) -, SchemaEntry("ifcidentifier",NULL ) -, SchemaEntry("ifcradioactivitymeasure",NULL ) -, SchemaEntry("ifcsymbolstyleselect",NULL ) -, SchemaEntry("ifcrooftypeenum",NULL ) -, SchemaEntry("ifcreal",NULL ) -, SchemaEntry("ifcroleenum",NULL ) -, SchemaEntry("ifcmeasurevalue",NULL ) -, SchemaEntry("ifcpiletypeenum",NULL ) -, SchemaEntry("ifcelectriccurrentenum",NULL ) -, SchemaEntry("ifctexttransformation",NULL ) -, SchemaEntry("ifcfiltertypeenum",NULL ) -, SchemaEntry("ifctransformertypeenum",NULL ) -, SchemaEntry("ifcsurfaceside",NULL ) -, SchemaEntry("ifcthermaltransmittancemeasure",NULL ) -, SchemaEntry("ifctubebundletypeenum",NULL ) -, SchemaEntry("ifclightfixturetypeenum",NULL ) -, SchemaEntry("ifcinductancemeasure",NULL ) -, SchemaEntry("ifcglobalorlocalenum",NULL ) -, SchemaEntry("ifcoutlettypeenum",NULL ) -, SchemaEntry("ifcworkcontroltypeenum",NULL ) -, SchemaEntry("ifcwarpingmomentmeasure",NULL ) -, SchemaEntry("ifcdynamicviscositymeasure",NULL ) -, SchemaEntry("ifcenergysequenceenum",NULL ) -, SchemaEntry("ifcfillareastyletileshapeselect",NULL ) -, SchemaEntry("ifcpointorvertexpoint",NULL ) -, SchemaEntry("ifcvibrationisolatortypeenum",NULL ) -, SchemaEntry("ifctanktypeenum",NULL ) -, SchemaEntry("ifctimeseriesdatatypeenum",NULL ) -, SchemaEntry("ifcsurfacetextureenum",NULL ) -, SchemaEntry("ifcaddresstypeenum",NULL ) -, SchemaEntry("ifcchillertypeenum",NULL ) -, SchemaEntry("ifccomplexnumber",NULL ) -, SchemaEntry("ifclightdistributioncurveenum",NULL ) -, SchemaEntry("ifcreinforcingbarroleenum",NULL ) , SchemaEntry("ifcresourceconsumptionenum",NULL ) -, SchemaEntry("ifccsgselect",NULL ) -, SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",NULL ) -, SchemaEntry("ifcevaporatortypeenum",NULL ) -, SchemaEntry("ifctimeseriesscheduletypeenum",NULL ) -, SchemaEntry("ifcdayinmonthnumber",NULL ) -, SchemaEntry("ifcelectricmotortypeenum",NULL ) -, SchemaEntry("ifcthermalconductivitymeasure",NULL ) -, SchemaEntry("ifcenergymeasure",NULL ) -, SchemaEntry("ifcrotationalstiffnessmeasure",NULL ) -, SchemaEntry("ifcderivedmeasurevalue",NULL ) -, SchemaEntry("ifcdoorpaneloperationenum",NULL ) -, SchemaEntry("ifccurvestylefontselect",NULL ) -, SchemaEntry("ifcwindowpaneloperationenum",NULL ) -, SchemaEntry("ifcdataoriginenum",NULL ) -, SchemaEntry("ifcstairtypeenum",NULL ) +, SchemaEntry("ifcelectriccapacitancemeasure",NULL ) +, SchemaEntry("ifclayersetdirectionenum",NULL ) , SchemaEntry("ifcrailingtypeenum",NULL ) -, SchemaEntry("ifcpowermeasure",NULL ) +, SchemaEntry("ifcobjectiveenum",NULL ) +, SchemaEntry("ifcdocumentselect",NULL ) +, SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",NULL ) +, SchemaEntry("ifcthermaladmittancemeasure",NULL ) +, SchemaEntry("ifctransitioncode",NULL ) +, SchemaEntry("ifcconnectiontypeenum",NULL ) +, SchemaEntry("ifcmonetarymeasure",NULL ) , SchemaEntry("ifcstackterminaltypeenum",NULL ) -, SchemaEntry("ifchatchlinedistanceselect",NULL ) -, SchemaEntry("ifctrimmingselect",NULL ) -, SchemaEntry("ifcthermalexpansioncoefficientmeasure",NULL ) -, SchemaEntry("ifclightdistributiondatasourceselect",NULL ) -, SchemaEntry("ifctorquemeasure",NULL ) -, SchemaEntry("ifcmassperlengthmeasure",NULL ) -, SchemaEntry("ifcvalvetypeenum",NULL ) -, SchemaEntry("ifcwindowpanelpositionenum",NULL ) -, SchemaEntry("ifcsurfaceorfacesurface",NULL ) +, SchemaEntry("ifccolour",NULL ) +, SchemaEntry("ifctext",NULL ) +, SchemaEntry("ifccontextdependentmeasure",NULL ) +, SchemaEntry("ifcthermalconductivitymeasure",NULL ) +, SchemaEntry("ifcprojectedortruelengthenum",NULL ) +, SchemaEntry("ifcpressuremeasure",NULL ) +, SchemaEntry("ifcmoisturediffusivitymeasure",NULL ) +, SchemaEntry("ifcbooleanoperator",NULL ) , SchemaEntry("ifcpropertysourceenum",NULL ) -, SchemaEntry("ifccablecarriersegmenttypeenum",NULL ) -, SchemaEntry("ifccountmeasure",NULL ) -, SchemaEntry("ifcfontweight",NULL ) -, SchemaEntry("ifcphysicalorvirtualenum",NULL ) -, SchemaEntry("ifcspacetypeenum",NULL ) -, SchemaEntry("ifcvolumetricflowratemeasure",NULL ) -, SchemaEntry("ifcluminousfluxmeasure",NULL ) -, SchemaEntry("ifcevaporativecoolertypeenum",NULL ) -, SchemaEntry("ifclayereditem",NULL ) -, SchemaEntry("ifcmodulusofsubgradereactionmeasure",NULL ) -, SchemaEntry("ifcheatexchangertypeenum",NULL ) -, SchemaEntry("ifcprotectivedevicetypeenum",NULL ) -, SchemaEntry("ifcdampertypeenum",NULL ) -, SchemaEntry("ifccontrollertypeenum",NULL ) -, SchemaEntry("ifcmassflowratemeasure",NULL ) -, SchemaEntry("ifcassemblyplaceenum",NULL ) -, SchemaEntry("ifcareameasure",NULL ) -, SchemaEntry("ifcservicelifefactortypeenum",NULL ) -, SchemaEntry("ifcvolumemeasure",NULL ) -, SchemaEntry("ifcbeamtypeenum",NULL ) -, SchemaEntry("ifcstateenum",NULL ) -, SchemaEntry("ifcspaceheatertypeenum",NULL ) -, SchemaEntry("ifcsectiontypeenum",NULL ) -, SchemaEntry("ifcfootingtypeenum",NULL ) -, SchemaEntry("ifcmonetarymeasure",NULL ) -, SchemaEntry("ifcloadgrouptypeenum",NULL ) -, SchemaEntry("ifcelectricgeneratortypeenum",NULL ) -, SchemaEntry("ifcflowmetertypeenum",NULL ) +, SchemaEntry("ifctimestamp",NULL ) , SchemaEntry("ifcmaterialselect",NULL ) -, SchemaEntry("ifcanalysismodeltypeenum",NULL ) -, SchemaEntry("ifctemperaturegradientmeasure",NULL ) -, SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",NULL ) -, SchemaEntry("ifccolour",NULL ) -, SchemaEntry("ifccurtainwalltypeenum",NULL ) -, SchemaEntry("ifcmetricvalueselect",NULL ) -, SchemaEntry("ifctextalignment",NULL ) -, SchemaEntry("ifcdoorpanelpositionenum",NULL ) -, SchemaEntry("ifcplatetypeenum",NULL ) -, SchemaEntry("ifcsectionalareaintegralmeasure",NULL ) -, SchemaEntry("ifcpresentabletext",NULL ) +, SchemaEntry("ifcgloballyuniqueid",NULL ) +, SchemaEntry("ifcreflectancemethodenum",NULL ) , SchemaEntry("ifcvaporpermeabilitymeasure",NULL ) -, SchemaEntry("ifcstructuralsurfacetypeenum",NULL ) +, SchemaEntry("ifctimeseriesscheduletypeenum",NULL ) +, SchemaEntry("ifclinearmomentmeasure",NULL ) +, SchemaEntry("ifcgeometricsetselect",NULL ) +, SchemaEntry("ifcsectionmodulusmeasure",NULL ) +, SchemaEntry("ifcbsplinecurveform",NULL ) +, SchemaEntry("ifcdimensionextentusage",NULL ) +, SchemaEntry("ifcthermalexpansioncoefficientmeasure",NULL ) +, SchemaEntry("ifchourinday",NULL ) , SchemaEntry("ifclinearvelocitymeasure",NULL ) -, SchemaEntry("ifcintegercountratemeasure",NULL ) -, SchemaEntry("ifcairtoairheatrecoverytypeenum",NULL ) -, SchemaEntry("ifcdocumentstatusenum",NULL ) -, SchemaEntry("ifclengthmeasure",NULL ) -, SchemaEntry("ifcplanarforcemeasure",NULL ) -, SchemaEntry("ifcbooleanoperand",NULL ) -, SchemaEntry("ifcinteger",NULL ) -, SchemaEntry("ifcramptypeenum",NULL ) -, SchemaEntry("ifcactorselect",NULL ) +, SchemaEntry("ifctorquemeasure",NULL ) +, SchemaEntry("ifctemperaturegradientmeasure",NULL ) +, SchemaEntry("ifcfillstyleselect",NULL ) , SchemaEntry("ifcelectricchargemeasure",NULL ) -, SchemaEntry("ifcgeometricsetselect",NULL ) -, SchemaEntry("ifcconnectiontypeenum",NULL ) -, SchemaEntry("ifcvalue",NULL ) +, SchemaEntry("ifcheatexchangertypeenum",NULL ) +, SchemaEntry("ifcelectriccurrentenum",NULL ) +, SchemaEntry("ifcdaylightsavinghour",NULL ) +, SchemaEntry("ifcshell",NULL ) +, SchemaEntry("ifcdoseequivalentmeasure",NULL ) +, SchemaEntry("ifcprojectordertypeenum",NULL ) +, SchemaEntry("ifcderivedmeasurevalue",NULL ) +, SchemaEntry("ifclightdistributioncurveenum",NULL ) +, SchemaEntry("ifcwarpingmomentmeasure",NULL ) +, SchemaEntry("ifcmembertypeenum",NULL ) +, SchemaEntry("ifcsoundpowermeasure",NULL ) +, SchemaEntry("ifctextalignment",NULL ) +, SchemaEntry("ifccurveoredgecurve",NULL ) +, SchemaEntry("ifcmassflowratemeasure",NULL ) +, SchemaEntry("ifcisothermalmoisturecapacitymeasure",NULL ) +, SchemaEntry("ifccsgselect",NULL ) , SchemaEntry("ifccoolingtowertypeenum",NULL ) -, SchemaEntry("ifcplaneanglemeasure",NULL ) -, SchemaEntry("ifcswitchingdevicetypeenum",NULL ) +, SchemaEntry("ifcmassmeasure",NULL ) +, SchemaEntry("ifcpileconstructionenum",NULL ) +, SchemaEntry("ifcdoorstyleoperationenum",NULL ) , SchemaEntry("ifcflowdirectionenum",NULL ) , SchemaEntry("ifcthermalloadsourceenum",NULL ) -, SchemaEntry("ifctextfontselect",NULL ) -, SchemaEntry("ifcspecularhighlightselect",NULL ) -, SchemaEntry("ifcanalysistheorytypeenum",NULL ) -, SchemaEntry("ifctextfontname",NULL ) -, SchemaEntry("ifcelectricvoltagemeasure",NULL ) -, SchemaEntry("ifctendontypeenum",NULL ) -, SchemaEntry("ifcsoundpressuremeasure",NULL ) -, SchemaEntry("ifcelectricdistributionpointfunctionenum",NULL ) -, SchemaEntry("ifcspecularroughness",NULL ) -, SchemaEntry("ifcactiontypeenum",NULL ) +, SchemaEntry("ifclengthmeasure",NULL ) +, SchemaEntry("ifcconstraintenum",NULL ) +, SchemaEntry("ifcaxis2placement",NULL ) +, SchemaEntry("ifcloadgrouptypeenum",NULL ) +, SchemaEntry("ifcvalue",NULL ) , SchemaEntry("ifcreinforcingbarsurfaceenum",NULL ) -, SchemaEntry("ifchumidifiertypeenum",NULL ) -, SchemaEntry("ifcilluminancemeasure",NULL ) -, SchemaEntry("ifclibraryselect",NULL ) -, SchemaEntry("ifctext",NULL ) -, SchemaEntry("ifclayersetdirectionenum",NULL ) -, SchemaEntry("ifcboilertypeenum",NULL ) -, SchemaEntry("ifctimemeasure",NULL ) +, SchemaEntry("ifcprojectorderrecordtypeenum",NULL ) +, SchemaEntry("ifcdatetimeselect",NULL ) +, SchemaEntry("ifcstructuralsurfacetypeenum",NULL ) +, SchemaEntry("ifcpermeablecoveringoperationenum",NULL ) +, SchemaEntry("ifcfontweight",NULL ) +, SchemaEntry("ifcphmeasure",NULL ) +, SchemaEntry("ifcdescriptivemeasure",NULL ) +, SchemaEntry("ifccurvestylefontselect",NULL ) +, SchemaEntry("ifcunit",NULL ) +, SchemaEntry("ifchatchlinedistanceselect",NULL ) +, SchemaEntry("ifctextstyleselect",NULL ) +, SchemaEntry("ifcmetricvalueselect",NULL ) +, SchemaEntry("ifcvectorordirection",NULL ) +, SchemaEntry("ifcassemblyplaceenum",NULL ) +, SchemaEntry("ifcairterminaltypeenum",NULL ) +, SchemaEntry("ifccoveringtypeenum",NULL ) +, SchemaEntry("ifcplanarforcemeasure",NULL ) +, SchemaEntry("ifcvalvetypeenum",NULL ) +, SchemaEntry("ifcalarmtypeenum",NULL ) +, SchemaEntry("ifcdynamicviscositymeasure",NULL ) +, SchemaEntry("ifccurrencyenum",NULL ) +, SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",NULL ) +, SchemaEntry("ifccablecarrierfittingtypeenum",NULL ) +, SchemaEntry("ifcboolean",NULL ) +, SchemaEntry("ifcactionsourcetypeenum",NULL ) +, SchemaEntry("ifcstructuralactivityassignmentselect",NULL ) +, SchemaEntry("ifcdistributionchamberelementtypeenum",NULL ) +, SchemaEntry("ifcevaporativecoolertypeenum",NULL ) +, SchemaEntry("ifcmagneticfluxdensitymeasure",NULL ) +, SchemaEntry("ifclightdistributiondatasourceselect",NULL ) +, SchemaEntry("ifctubebundletypeenum",NULL ) , SchemaEntry("ifcaccelerationmeasure",NULL ) -, SchemaEntry("ifcelectricflowstoragedevicetypeenum",NULL ) -, SchemaEntry("ifcluminousintensitymeasure",NULL ) +, SchemaEntry("ifcboilertypeenum",NULL ) +, SchemaEntry("ifcramptypeenum",NULL ) +, SchemaEntry("ifcluminousintensitydistributionmeasure",NULL ) +, SchemaEntry("ifctrimmingpreference",NULL ) +, SchemaEntry("ifcspecificheatcapacitymeasure",NULL ) +, SchemaEntry("ifcamountofsubstancemeasure",NULL ) +, SchemaEntry("ifcroleenum",NULL ) +, SchemaEntry("ifcdocumentconfidentialityenum",NULL ) +, SchemaEntry("ifcfrequencymeasure",NULL ) +, SchemaEntry("ifcsectiontypeenum",NULL ) +, SchemaEntry("ifcelementassemblytypeenum",NULL ) +, SchemaEntry("ifcfootingtypeenum",NULL ) +, SchemaEntry("ifclayereditem",NULL ) +, SchemaEntry("ifccablesegmenttypeenum",NULL ) , SchemaEntry("ifcdefinedsymbolselect",NULL ) +, SchemaEntry("ifcbuildingelementproxytypeenum",NULL ) +, SchemaEntry("ifcelectricgeneratortypeenum",NULL ) +, SchemaEntry("ifcrotationalstiffnessmeasure",NULL ) +, SchemaEntry("ifcspaceheatertypeenum",NULL ) +, SchemaEntry("ifcareameasure",NULL ) +, SchemaEntry("ifclabel",NULL ) +, SchemaEntry("ifccostscheduletypeenum",NULL ) +, SchemaEntry("ifcswitchingdevicetypeenum",NULL ) +, SchemaEntry("ifcelectrictimecontroltypeenum",NULL ) +, SchemaEntry("ifcfiltertypeenum",NULL ) +, SchemaEntry("ifcpositivelengthmeasure",NULL ) +, SchemaEntry("ifcnullstyle",NULL ) +, SchemaEntry("ifcconditioncriterionselect",NULL ) +, SchemaEntry("ifcshearmodulusmeasure",NULL ) +, SchemaEntry("ifcnormalisedratiomeasure",NULL ) +, SchemaEntry("ifcdoorpaneloperationenum",NULL ) +, SchemaEntry("ifcpointorvertexpoint",NULL ) +, SchemaEntry("ifcrooftypeenum",NULL ) +, SchemaEntry("ifccountmeasure",NULL ) +, SchemaEntry("ifcelectricconductancemeasure",NULL ) +, SchemaEntry("ifcproceduretypeenum",NULL ) +, SchemaEntry("ifcflowinstrumenttypeenum",NULL ) +, SchemaEntry("ifcelectricmotortypeenum",NULL ) +, SchemaEntry("ifcsurfaceside",NULL ) +, SchemaEntry("ifcstructuralcurvetypeenum",NULL ) +, SchemaEntry("ifccondensertypeenum",NULL ) +, SchemaEntry("ifclinearstiffnessmeasure",NULL ) , SchemaEntry("ifcunitenum",NULL ) -, SchemaEntry("ifcinventorytypeenum",NULL ) -, SchemaEntry("ifcstructuralactivityassignmentselect",NULL ) -, SchemaEntry("ifcelementassemblytypeenum",NULL ) -, SchemaEntry("ifcservicelifetypeenum",NULL ) -, SchemaEntry("ifccoveringtypeenum",NULL ) -, SchemaEntry("ifcstairflighttypeenum",NULL ) +, SchemaEntry("ifcoccupanttypeenum",NULL ) +, SchemaEntry("ifcthermalloadtypeenum",NULL ) +, SchemaEntry("ifcreinforcingbarroleenum",NULL ) +, SchemaEntry("ifcbenchmarkenum",NULL ) +, SchemaEntry("ifcpositiveplaneanglemeasure",NULL ) +, SchemaEntry("ifctexttransformation",NULL ) +, SchemaEntry("ifcdraughtingcalloutelement",NULL ) +, SchemaEntry("ifcratiomeasure",NULL ) +, SchemaEntry("ifcsolidanglemeasure",NULL ) +, SchemaEntry("ifcpipesegmenttypeenum",NULL ) +, SchemaEntry("ifccablecarriersegmenttypeenum",NULL ) +, SchemaEntry("ifccolourorfactor",NULL ) +, SchemaEntry("ifcidentifier",NULL ) +, SchemaEntry("ifctendontypeenum",NULL ) +, SchemaEntry("ifccontrollertypeenum",NULL ) +, SchemaEntry("ifcradioactivitymeasure",NULL ) +, SchemaEntry("ifctimemeasure",NULL ) +, SchemaEntry("ifcpumptypeenum",NULL ) +, SchemaEntry("ifcelectricheatertypeenum",NULL ) +, SchemaEntry("ifcbeamtypeenum",NULL ) +, SchemaEntry("ifcstateenum",NULL ) , SchemaEntry("ifcsiprefix",NULL ) -, SchemaEntry("ifcelectriccapacitancemeasure",NULL ) -, SchemaEntry("ifcflowinstrumenttypeenum",NULL ) +, SchemaEntry("ifcnumericmeasure",NULL ) +, SchemaEntry("ifcoutlettypeenum",NULL ) +, SchemaEntry("ifccompoundplaneanglemeasure",NULL ) +, SchemaEntry("ifcservicelifefactortypeenum",NULL ) +, SchemaEntry("ifclogicaloperatorenum",NULL ) +, SchemaEntry("ifcbooleanoperand",NULL ) +, SchemaEntry("ifcobjectreferenceselect",NULL ) +, SchemaEntry("ifccooledbeamtypeenum",NULL ) +, SchemaEntry("ifcductsilencertypeenum",NULL ) +, SchemaEntry("ifcsectionalareaintegralmeasure",NULL ) +, SchemaEntry("ifcfontvariant",NULL ) +, SchemaEntry("ifcvolumetricflowratemeasure",NULL ) +, SchemaEntry("ifcplatetypeenum",NULL ) +, SchemaEntry("ifcenvironmentalimpactcategoryenum",NULL ) +, SchemaEntry("ifcvibrationisolatortypeenum",NULL ) , SchemaEntry("ifcthermodynamictemperaturemeasure",NULL ) -, SchemaEntry("ifcgloballyuniqueid",NULL ) -, SchemaEntry("ifclamptypeenum",NULL ) -, SchemaEntry("ifcmagneticfluxmeasure",NULL ) -, SchemaEntry("ifcsolidanglemeasure",NULL ) -, SchemaEntry("ifcfrequencymeasure",NULL ) -, SchemaEntry("ifctransportelementtypeenum",NULL ) -, SchemaEntry("ifcsoundscaleenum",NULL ) -, SchemaEntry("ifcphmeasure",NULL ) -, SchemaEntry("ifcactuatortypeenum",NULL ) -, SchemaEntry("ifcpositiveplaneanglemeasure",NULL ) -, SchemaEntry("ifcappliedvalueselect",NULL ) +, SchemaEntry("ifcrotationalmassmeasure",NULL ) , SchemaEntry("ifcsecondinminute",NULL ) -, SchemaEntry("ifcductsegmenttypeenum",NULL ) -, SchemaEntry("ifcthermaladmittancemeasure",NULL ) -, SchemaEntry("ifcspecularexponent",NULL ) -, SchemaEntry("ifcdatetimeselect",NULL ) -, SchemaEntry("ifctransitioncode",NULL ) +, SchemaEntry("ifcdayinmonthnumber",NULL ) , SchemaEntry("ifcdimensioncount",NULL ) -, SchemaEntry("ifclinearstiffnessmeasure",NULL ) -, SchemaEntry("ifccompoundplaneanglemeasure",NULL ) -, SchemaEntry("ifcelectricappliancetypeenum",NULL ) +, SchemaEntry("ifcwindowstyleoperationenum",NULL ) +, SchemaEntry("ifcthermalresistancemeasure",NULL ) +, SchemaEntry("ifcmeasurevalue",NULL ) +, SchemaEntry("ifcwindowpaneloperationenum",NULL ) +, SchemaEntry("ifcchillertypeenum",NULL ) +, SchemaEntry("ifcpositiveratiomeasure",NULL ) +, SchemaEntry("ifcinteger",NULL ) +, SchemaEntry("ifclogical",NULL ) +, SchemaEntry("ifcjunctionboxtypeenum",NULL ) +, SchemaEntry("ifcaddresstypeenum",NULL ) +, SchemaEntry("ifcwasteterminaltypeenum",NULL ) +, SchemaEntry("ifctrimmingselect",NULL ) +, SchemaEntry("ifclightemissionsourceenum",NULL ) +, SchemaEntry("ifcsoundscaleenum",NULL ) +, SchemaEntry("ifcluminousfluxmeasure",NULL ) +, SchemaEntry("ifcelectricresistancemeasure",NULL ) +, SchemaEntry("ifcintegercountratemeasure",NULL ) +, SchemaEntry("ifcphysicalorvirtualenum",NULL ) +, SchemaEntry("ifcmolecularweightmeasure",NULL ) , SchemaEntry("ifcprofiletypeenum",NULL ) +, SchemaEntry("ifcboxalignment",NULL ) +, SchemaEntry("ifcglobalorlocalenum",NULL ) +, SchemaEntry("ifcspecularroughness",NULL ) +, SchemaEntry("ifclamptypeenum",NULL ) +, SchemaEntry("ifcpiletypeenum",NULL ) +, SchemaEntry("ifcelectriccurrentmeasure",NULL ) +, SchemaEntry("ifcfantypeenum",NULL ) +, SchemaEntry("ifcsurfaceorfacesurface",NULL ) +, SchemaEntry("ifcpipefittingtypeenum",NULL ) +, SchemaEntry("ifctanktypeenum",NULL ) , SchemaEntry("ifccurvefontorscaledcurvefontselect",NULL ) -, SchemaEntry("ifcprojectedortruelengthenum",NULL ) -, SchemaEntry("ifcabsorbeddosemeasure",NULL ) -, SchemaEntry("ifcparametervalue",NULL ) -, SchemaEntry("ifcpileconstructionenum",NULL ) +, SchemaEntry("ifcwindowstyleconstructionenum",NULL ) +, SchemaEntry("ifcairterminalboxtypeenum",NULL ) +, SchemaEntry("ifcstairflighttypeenum",NULL ) +, SchemaEntry("ifcluminousintensitymeasure",NULL ) , SchemaEntry("ifcmotorconnectiontypeenum",NULL ) -, SchemaEntry("ifcoccupanttypeenum",NULL ) -, SchemaEntry("ifcunit",NULL ) -, SchemaEntry("ifclinearforcemeasure",NULL ) -, SchemaEntry("ifccondensertypeenum",NULL ) -, SchemaEntry("ifcdescriptivemeasure",NULL ) -, SchemaEntry("ifcmomentofinertiameasure",NULL ) -, SchemaEntry("ifcdoseequivalentmeasure",NULL ) -, SchemaEntry("ifcorientationselect",NULL ) -, SchemaEntry("ifclogical",NULL ) -, SchemaEntry("ifcsizeselect",NULL ) -, SchemaEntry("ifcenvironmentalimpactcategoryenum",NULL ) -, SchemaEntry("ifclogicaloperatorenum",NULL ) -, SchemaEntry("ifccompressortypeenum",NULL ) -, SchemaEntry("ifcbenchmarkenum",NULL ) -, SchemaEntry("ifcratiomeasure",NULL ) -, SchemaEntry("ifcvectorordirection",NULL ) -, SchemaEntry("ifcconstraintenum",NULL ) -, SchemaEntry("ifcalarmtypeenum",NULL ) -, SchemaEntry("ifcluminousintensitydistributionmeasure",NULL ) -, SchemaEntry("ifcarithmeticoperatorenum",NULL ) -, SchemaEntry("ifcaxis2placement",NULL ) -, SchemaEntry("ifcforcemeasure",NULL ) -, SchemaEntry("ifctrimmingpreference",NULL ) -, SchemaEntry("ifcelectricresistancemeasure",NULL ) -, SchemaEntry("ifcwarpingconstantmeasure",NULL ) -, SchemaEntry("ifcpipesegmenttypeenum",NULL ) -, SchemaEntry("ifcconditioncriterionselect",NULL ) -, SchemaEntry("ifcshearmodulusmeasure",NULL ) -, SchemaEntry("ifcpressuremeasure",NULL ) -, SchemaEntry("ifcductsilencertypeenum",NULL ) -, SchemaEntry("ifcboolean",NULL ) -, SchemaEntry("ifcsectionmodulusmeasure",NULL ) -, SchemaEntry("ifcchangeactionenum",NULL ) +, SchemaEntry("ifcplaneanglemeasure",NULL ) +, SchemaEntry("ifcactuatortypeenum",NULL ) +, SchemaEntry("ifccolumntypeenum",NULL ) +, SchemaEntry("ifctextfontselect",NULL ) +, SchemaEntry("ifcdoorpanelpositionenum",NULL ) , SchemaEntry("ifccoiltypeenum",NULL ) -, SchemaEntry("ifcmassmeasure",NULL ) -, SchemaEntry("ifcstructuralcurvetypeenum",NULL ) -, SchemaEntry("ifcpermeablecoveringoperationenum",NULL ) -, SchemaEntry("ifcmagneticfluxdensitymeasure",NULL ) -, SchemaEntry("ifcmoisturediffusivitymeasure",NULL ) +, SchemaEntry("ifcangularvelocitymeasure",NULL ) +, SchemaEntry("ifcanalysismodeltypeenum",NULL ) +, SchemaEntry("ifclibraryselect",NULL ) +, SchemaEntry("ifcforcemeasure",NULL ) +, SchemaEntry("ifcfillareastyletileshapeselect",NULL ) +, SchemaEntry("ifcelectricappliancetypeenum",NULL ) +, SchemaEntry("ifcsurfacetextureenum",NULL ) +, SchemaEntry("ifccharacterstyleselect",NULL ) +, SchemaEntry("ifcenergymeasure",NULL ) +, SchemaEntry("ifcreal",NULL ) +, SchemaEntry("ifccompressortypeenum",NULL ) +, SchemaEntry("ifcelectricdistributionpointfunctionenum",NULL ) , SchemaEntry("ifcroot",&STEP::ObjectHelper<IfcRoot,4>::Construct ) , SchemaEntry("ifcobjectdefinition",&STEP::ObjectHelper<IfcObjectDefinition,0>::Construct ) , SchemaEntry("ifctypeobject",&STEP::ObjectHelper<IfcTypeObject,2>::Construct ) , SchemaEntry("ifctypeproduct",&STEP::ObjectHelper<IfcTypeProduct,2>::Construct ) , SchemaEntry("ifcelementtype",&STEP::ObjectHelper<IfcElementType,1>::Construct ) -, SchemaEntry("ifcfurnishingelementtype",&STEP::ObjectHelper<IfcFurnishingElementType,0>::Construct ) -, SchemaEntry("ifcfurnituretype",&STEP::ObjectHelper<IfcFurnitureType,1>::Construct ) +, SchemaEntry("ifcdistributionelementtype",&STEP::ObjectHelper<IfcDistributionElementType,0>::Construct ) +, SchemaEntry("ifcdistributionflowelementtype",&STEP::ObjectHelper<IfcDistributionFlowElementType,0>::Construct ) +, SchemaEntry("ifcflowcontrollertype",&STEP::ObjectHelper<IfcFlowControllerType,0>::Construct ) +, SchemaEntry("ifcelectrictimecontroltype",&STEP::ObjectHelper<IfcElectricTimeControlType,1>::Construct ) +, SchemaEntry("ifcrepresentation",&STEP::ObjectHelper<IfcRepresentation,4>::Construct ) +, SchemaEntry("ifcshapemodel",&STEP::ObjectHelper<IfcShapeModel,0>::Construct ) +, SchemaEntry("ifctopologyrepresentation",&STEP::ObjectHelper<IfcTopologyRepresentation,0>::Construct ) +, SchemaEntry("ifcrelationship",&STEP::ObjectHelper<IfcRelationship,0>::Construct ) +, SchemaEntry("ifcrelconnects",&STEP::ObjectHelper<IfcRelConnects,0>::Construct ) +, SchemaEntry("ifcrelcoversspaces",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowfittingtype",&STEP::ObjectHelper<IfcFlowFittingType,0>::Construct ) +, SchemaEntry("ifccablecarrierfittingtype",&STEP::ObjectHelper<IfcCableCarrierFittingType,1>::Construct ) +, SchemaEntry("ifcstructuralconnectioncondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcslippageconnectioncondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcenergyconversiondevicetype",&STEP::ObjectHelper<IfcEnergyConversionDeviceType,0>::Construct ) +, SchemaEntry("ifccoiltype",&STEP::ObjectHelper<IfcCoilType,1>::Construct ) , SchemaEntry("ifcobject",&STEP::ObjectHelper<IfcObject,1>::Construct ) -, SchemaEntry("ifcproduct",&STEP::ObjectHelper<IfcProduct,2>::Construct ) -, SchemaEntry("ifcgrid",&STEP::ObjectHelper<IfcGrid,3>::Construct ) +, SchemaEntry("ifccontrol",&STEP::ObjectHelper<IfcControl,0>::Construct ) +, SchemaEntry("ifcperformancehistory",&STEP::ObjectHelper<IfcPerformanceHistory,1>::Construct ) , SchemaEntry("ifcrepresentationitem",&STEP::ObjectHelper<IfcRepresentationItem,0>::Construct ) , SchemaEntry("ifcgeometricrepresentationitem",&STEP::ObjectHelper<IfcGeometricRepresentationItem,0>::Construct ) -, SchemaEntry("ifconedirectionrepeatfactor",&STEP::ObjectHelper<IfcOneDirectionRepeatFactor,1>::Construct ) -, SchemaEntry("ifctwodirectionrepeatfactor",&STEP::ObjectHelper<IfcTwoDirectionRepeatFactor,1>::Construct ) +, SchemaEntry("ifctextliteral",&STEP::ObjectHelper<IfcTextLiteral,3>::Construct ) +, SchemaEntry("ifctextliteralwithextent",&STEP::ObjectHelper<IfcTextLiteralWithExtent,2>::Construct ) +, SchemaEntry("ifcproductrepresentation",&STEP::ObjectHelper<IfcProductRepresentation,3>::Construct ) +, SchemaEntry("ifcproduct",&STEP::ObjectHelper<IfcProduct,2>::Construct ) , SchemaEntry("ifcelement",&STEP::ObjectHelper<IfcElement,1>::Construct ) -, SchemaEntry("ifcelementcomponent",&STEP::ObjectHelper<IfcElementComponent,0>::Construct ) -, SchemaEntry("ifclocaltime",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcspatialstructureelementtype",&STEP::ObjectHelper<IfcSpatialStructureElementType,0>::Construct ) -, SchemaEntry("ifccontrol",&STEP::ObjectHelper<IfcControl,0>::Construct ) -, SchemaEntry("ifcactionrequest",&STEP::ObjectHelper<IfcActionRequest,1>::Construct ) -, SchemaEntry("ifctexturevertex",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpropertydefinition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpropertysetdefinition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcfluidflowproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdocumentinformation",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccalendardate",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdistributionelementtype",&STEP::ObjectHelper<IfcDistributionElementType,0>::Construct ) -, SchemaEntry("ifcdistributionflowelementtype",&STEP::ObjectHelper<IfcDistributionFlowElementType,0>::Construct ) -, SchemaEntry("ifcenergyconversiondevicetype",&STEP::ObjectHelper<IfcEnergyConversionDeviceType,0>::Construct ) -, SchemaEntry("ifccooledbeamtype",&STEP::ObjectHelper<IfcCooledBeamType,1>::Construct ) -, SchemaEntry("ifccsgprimitive3d",&STEP::ObjectHelper<IfcCsgPrimitive3D,1>::Construct ) -, SchemaEntry("ifcrectangularpyramid",&STEP::ObjectHelper<IfcRectangularPyramid,3>::Construct ) -, SchemaEntry("ifcstructuralload",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralloadstatic",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralloadlinearforce",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdistributionelement",&STEP::ObjectHelper<IfcDistributionElement,0>::Construct ) +, SchemaEntry("ifcdistributionflowelement",&STEP::ObjectHelper<IfcDistributionFlowElement,0>::Construct ) +, SchemaEntry("ifccurve",&STEP::ObjectHelper<IfcCurve,0>::Construct ) +, SchemaEntry("ifcboundedcurve",&STEP::ObjectHelper<IfcBoundedCurve,0>::Construct ) +, SchemaEntry("ifccompositecurve",&STEP::ObjectHelper<IfcCompositeCurve,2>::Construct ) +, SchemaEntry("ifc2dcompositecurve",&STEP::ObjectHelper<Ifc2DCompositeCurve,0>::Construct ) +, SchemaEntry("ifcboundarycondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcboundaryfacecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccartesiantransformationoperator",&STEP::ObjectHelper<IfcCartesianTransformationOperator,4>::Construct ) +, SchemaEntry("ifccartesiantransformationoperator3d",&STEP::ObjectHelper<IfcCartesianTransformationOperator3D,1>::Construct ) +, SchemaEntry("ifcproperty",&STEP::ObjectHelper<IfcProperty,2>::Construct ) +, SchemaEntry("ifcsimpleproperty",&STEP::ObjectHelper<IfcSimpleProperty,0>::Construct ) +, SchemaEntry("ifcpropertyenumeratedvalue",&STEP::ObjectHelper<IfcPropertyEnumeratedValue,2>::Construct ) +, SchemaEntry("ifcpresentationlayerassignment",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpresentationlayerwithstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcbuildingelementtype",&STEP::ObjectHelper<IfcBuildingElementType,0>::Construct ) +, SchemaEntry("ifcstairflighttype",&STEP::ObjectHelper<IfcStairFlightType,1>::Construct ) , SchemaEntry("ifcsurface",&STEP::ObjectHelper<IfcSurface,0>::Construct ) -, SchemaEntry("ifcboundedsurface",&STEP::ObjectHelper<IfcBoundedSurface,0>::Construct ) -, SchemaEntry("ifcrectangulartrimmedsurface",&STEP::ObjectHelper<IfcRectangularTrimmedSurface,7>::Construct ) -, SchemaEntry("ifcphysicalquantity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcphysicalsimplequantity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcquantityvolume",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcquantityarea",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcgroup",&STEP::ObjectHelper<IfcGroup,0>::Construct ) -, SchemaEntry("ifcrelationship",&STEP::ObjectHelper<IfcRelationship,0>::Construct ) -, SchemaEntry("ifcrelassigns",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassignstoactor",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifchalfspacesolid",&STEP::ObjectHelper<IfcHalfSpaceSolid,2>::Construct ) -, SchemaEntry("ifcpolygonalboundedhalfspace",&STEP::ObjectHelper<IfcPolygonalBoundedHalfSpace,2>::Construct ) -, SchemaEntry("ifcenergyproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcairtoairheatrecoverytype",&STEP::ObjectHelper<IfcAirToAirHeatRecoveryType,1>::Construct ) -, SchemaEntry("ifcflowfittingtype",&STEP::ObjectHelper<IfcFlowFittingType,0>::Construct ) -, SchemaEntry("ifcpipefittingtype",&STEP::ObjectHelper<IfcPipeFittingType,1>::Construct ) -, SchemaEntry("ifcrepresentation",&STEP::ObjectHelper<IfcRepresentation,4>::Construct ) -, SchemaEntry("ifcstylemodel",&STEP::ObjectHelper<IfcStyleModel,0>::Construct ) -, SchemaEntry("ifcstyledrepresentation",&STEP::ObjectHelper<IfcStyledRepresentation,0>::Construct ) -, SchemaEntry("ifcrelassignstocontrol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassignstoprojectorder",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdimensionalexponents",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcelementarysurface",&STEP::ObjectHelper<IfcElementarySurface,1>::Construct ) +, SchemaEntry("ifcplane",&STEP::ObjectHelper<IfcPlane,0>::Construct ) , SchemaEntry("ifcbooleanresult",&STEP::ObjectHelper<IfcBooleanResult,3>::Construct ) -, SchemaEntry("ifcsoundproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcfeatureelement",&STEP::ObjectHelper<IfcFeatureElement,0>::Construct ) -, SchemaEntry("ifcfeatureelementsubtraction",&STEP::ObjectHelper<IfcFeatureElementSubtraction,0>::Construct ) -, SchemaEntry("ifcopeningelement",&STEP::ObjectHelper<IfcOpeningElement,0>::Construct ) -, SchemaEntry("ifcconditioncriterion",&STEP::ObjectHelper<IfcConditionCriterion,2>::Construct ) +, SchemaEntry("ifcbooleanclippingresult",&STEP::ObjectHelper<IfcBooleanClippingResult,0>::Construct ) +, SchemaEntry("ifcsolidmodel",&STEP::ObjectHelper<IfcSolidModel,0>::Construct ) +, SchemaEntry("ifcmanifoldsolidbrep",&STEP::ObjectHelper<IfcManifoldSolidBrep,1>::Construct ) +, SchemaEntry("ifcprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcgeneralprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcflowterminaltype",&STEP::ObjectHelper<IfcFlowTerminalType,0>::Construct ) -, SchemaEntry("ifcflowcontrollertype",&STEP::ObjectHelper<IfcFlowControllerType,0>::Construct ) -, SchemaEntry("ifcswitchingdevicetype",&STEP::ObjectHelper<IfcSwitchingDeviceType,1>::Construct ) -, SchemaEntry("ifcsystem",&STEP::ObjectHelper<IfcSystem,0>::Construct ) -, SchemaEntry("ifcelectricalcircuit",&STEP::ObjectHelper<IfcElectricalCircuit,0>::Construct ) -, SchemaEntry("ifcactorrole",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdateandtime",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdraughtingcalloutrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdimensioncalloutrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcderivedunitelement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcexternalreference",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcclassificationreference",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcunitaryequipmenttype",&STEP::ObjectHelper<IfcUnitaryEquipmentType,1>::Construct ) -, SchemaEntry("ifcproperty",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcport",&STEP::ObjectHelper<IfcPort,0>::Construct ) -, SchemaEntry("ifcaddress",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcplacement",&STEP::ObjectHelper<IfcPlacement,1>::Construct ) -, SchemaEntry("ifcpredefineditem",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpredefinedcolour",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdraughtingpredefinedcolour",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcprofiledef",&STEP::ObjectHelper<IfcProfileDef,2>::Construct ) -, SchemaEntry("ifcarbitraryclosedprofiledef",&STEP::ObjectHelper<IfcArbitraryClosedProfileDef,1>::Construct ) -, SchemaEntry("ifccurve",&STEP::ObjectHelper<IfcCurve,0>::Construct ) -, SchemaEntry("ifcconic",&STEP::ObjectHelper<IfcConic,1>::Construct ) -, SchemaEntry("ifccircle",&STEP::ObjectHelper<IfcCircle,1>::Construct ) +, SchemaEntry("ifcstackterminaltype",&STEP::ObjectHelper<IfcStackTerminalType,1>::Construct ) +, SchemaEntry("ifcstructuralitem",&STEP::ObjectHelper<IfcStructuralItem,0>::Construct ) +, SchemaEntry("ifcstructuralconnection",&STEP::ObjectHelper<IfcStructuralConnection,1>::Construct ) +, SchemaEntry("ifcstructuralcurveconnection",&STEP::ObjectHelper<IfcStructuralCurveConnection,0>::Construct ) +, SchemaEntry("ifcjunctionboxtype",&STEP::ObjectHelper<IfcJunctionBoxType,1>::Construct ) +, SchemaEntry("ifcrelassociates",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelassociatesconstraint",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpropertydefinition",&STEP::ObjectHelper<IfcPropertyDefinition,0>::Construct ) +, SchemaEntry("ifcpropertysetdefinition",&STEP::ObjectHelper<IfcPropertySetDefinition,0>::Construct ) +, SchemaEntry("ifcdoorpanelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcconstraintrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcspacethermalloadproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifclibraryinformation",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcprocess",&STEP::ObjectHelper<IfcProcess,0>::Construct ) +, SchemaEntry("ifctask",&STEP::ObjectHelper<IfcTask,5>::Construct ) , SchemaEntry("ifcappliedvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcenvironmentalimpactvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsimpleproperty",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpropertysinglevalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcelementarysurface",&STEP::ObjectHelper<IfcElementarySurface,1>::Construct ) -, SchemaEntry("ifcplane",&STEP::ObjectHelper<IfcPlane,0>::Construct ) -, SchemaEntry("ifcpropertyboundedvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccostschedule",&STEP::ObjectHelper<IfcCostSchedule,8>::Construct ) -, SchemaEntry("ifcmonetaryunit",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconnectiongeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconnectioncurvegeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrightcircularcone",&STEP::ObjectHelper<IfcRightCircularCone,2>::Construct ) -, SchemaEntry("ifcelementassembly",&STEP::ObjectHelper<IfcElementAssembly,2>::Construct ) -, SchemaEntry("ifcbuildingelement",&STEP::ObjectHelper<IfcBuildingElement,0>::Construct ) -, SchemaEntry("ifcmember",&STEP::ObjectHelper<IfcMember,0>::Construct ) -, SchemaEntry("ifcpropertydependencyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcbuildingelementproxy",&STEP::ObjectHelper<IfcBuildingElementProxy,1>::Construct ) -, SchemaEntry("ifcstructuralactivity",&STEP::ObjectHelper<IfcStructuralActivity,2>::Construct ) -, SchemaEntry("ifcstructuralaction",&STEP::ObjectHelper<IfcStructuralAction,2>::Construct ) -, SchemaEntry("ifcstructuralplanaraction",&STEP::ObjectHelper<IfcStructuralPlanarAction,1>::Construct ) -, SchemaEntry("ifctopologicalrepresentationitem",&STEP::ObjectHelper<IfcTopologicalRepresentationItem,0>::Construct ) -, SchemaEntry("ifcconnectedfaceset",&STEP::ObjectHelper<IfcConnectedFaceSet,1>::Construct ) -, SchemaEntry("ifcsweptsurface",&STEP::ObjectHelper<IfcSweptSurface,2>::Construct ) -, SchemaEntry("ifcsurfaceoflinearextrusion",&STEP::ObjectHelper<IfcSurfaceOfLinearExtrusion,2>::Construct ) -, SchemaEntry("ifcarbitraryprofiledefwithvoids",&STEP::ObjectHelper<IfcArbitraryProfileDefWithVoids,1>::Construct ) -, SchemaEntry("ifcprocess",&STEP::ObjectHelper<IfcProcess,0>::Construct ) +, SchemaEntry("ifcrelfillselement",&STEP::ObjectHelper<IfcRelFillsElement,2>::Construct ) , SchemaEntry("ifcprocedure",&STEP::ObjectHelper<IfcProcedure,3>::Construct ) -, SchemaEntry("ifccurvestylefontpattern",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcvector",&STEP::ObjectHelper<IfcVector,2>::Construct ) -, SchemaEntry("ifcfacebound",&STEP::ObjectHelper<IfcFaceBound,2>::Construct ) -, SchemaEntry("ifcfaceouterbound",&STEP::ObjectHelper<IfcFaceOuterBound,0>::Construct ) -, SchemaEntry("ifcfeatureelementaddition",&STEP::ObjectHelper<IfcFeatureElementAddition,0>::Construct ) -, SchemaEntry("ifcnamedunit",&STEP::ObjectHelper<IfcNamedUnit,2>::Construct ) -, SchemaEntry("ifcconversionbasedunit",&STEP::ObjectHelper<IfcConversionBasedUnit,2>::Construct ) -, SchemaEntry("ifcstructuralloadsingleforce",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcheatexchangertype",&STEP::ObjectHelper<IfcHeatExchangerType,1>::Construct ) -, SchemaEntry("ifcpresentationstyleassignment",&STEP::ObjectHelper<IfcPresentationStyleAssignment,1>::Construct ) -, SchemaEntry("ifcflowtreatmentdevicetype",&STEP::ObjectHelper<IfcFlowTreatmentDeviceType,0>::Construct ) -, SchemaEntry("ifcfiltertype",&STEP::ObjectHelper<IfcFilterType,1>::Construct ) +, SchemaEntry("ifcstructuralload",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralloadstatic",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralloadsingledisplacement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcproxy",&STEP::ObjectHelper<IfcProxy,2>::Construct ) +, SchemaEntry("ifccurvestylefont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcresource",&STEP::ObjectHelper<IfcResource,0>::Construct ) -, SchemaEntry("ifcevaporativecoolertype",&STEP::ObjectHelper<IfcEvaporativeCoolerType,1>::Construct ) -, SchemaEntry("ifctexturecoordinate",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctexturecoordinategenerator",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcoffsetcurve2d",&STEP::ObjectHelper<IfcOffsetCurve2D,3>::Construct ) +, SchemaEntry("ifcconstructionresource",&STEP::ObjectHelper<IfcConstructionResource,4>::Construct ) +, SchemaEntry("ifcsubcontractresource",&STEP::ObjectHelper<IfcSubContractResource,2>::Construct ) +, SchemaEntry("ifccalendardate",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdocumentelectronicformat",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelcontainedinspatialstructure",&STEP::ObjectHelper<IfcRelContainedInSpatialStructure,2>::Construct ) +, SchemaEntry("ifcmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcproductsofcombustionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctopologicalrepresentationitem",&STEP::ObjectHelper<IfcTopologicalRepresentationItem,0>::Construct ) , SchemaEntry("ifcedge",&STEP::ObjectHelper<IfcEdge,2>::Construct ) -, SchemaEntry("ifcsubedge",&STEP::ObjectHelper<IfcSubedge,1>::Construct ) -, SchemaEntry("ifcproxy",&STEP::ObjectHelper<IfcProxy,2>::Construct ) -, SchemaEntry("ifcline",&STEP::ObjectHelper<IfcLine,2>::Construct ) -, SchemaEntry("ifccolumn",&STEP::ObjectHelper<IfcColumn,0>::Construct ) -, SchemaEntry("ifcclassificationnotationfacet",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcedgecurve",&STEP::ObjectHelper<IfcEdgeCurve,2>::Construct ) +, SchemaEntry("ifcplatetype",&STEP::ObjectHelper<IfcPlateType,1>::Construct ) , SchemaEntry("ifcobjectplacement",&STEP::ObjectHelper<IfcObjectPlacement,0>::Construct ) , SchemaEntry("ifcgridplacement",&STEP::ObjectHelper<IfcGridPlacement,2>::Construct ) -, SchemaEntry("ifcdistributioncontrolelementtype",&STEP::ObjectHelper<IfcDistributionControlElementType,0>::Construct ) -, SchemaEntry("ifcstructuralloadsingleforcewarping",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcexternallydefinedtextfont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelconnects",&STEP::ObjectHelper<IfcRelConnects,0>::Construct ) +, SchemaEntry("ifcfiresuppressionterminaltype",&STEP::ObjectHelper<IfcFireSuppressionTerminalType,1>::Construct ) +, SchemaEntry("ifcmechanicalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowstoragedevice",&STEP::ObjectHelper<IfcFlowStorageDevice,0>::Construct ) +, SchemaEntry("ifcperson",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsweptsurface",&STEP::ObjectHelper<IfcSweptSurface,2>::Construct ) +, SchemaEntry("ifcsurfaceofrevolution",&STEP::ObjectHelper<IfcSurfaceOfRevolution,1>::Construct ) +, SchemaEntry("ifcorientededge",&STEP::ObjectHelper<IfcOrientedEdge,2>::Construct ) +, SchemaEntry("ifcownerhistory",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelassigns",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelassignstoactor",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdirection",&STEP::ObjectHelper<IfcDirection,1>::Construct ) +, SchemaEntry("ifcreinforcementbarproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcprofiledef",&STEP::ObjectHelper<IfcProfileDef,2>::Construct ) +, SchemaEntry("ifcparameterizedprofiledef",&STEP::ObjectHelper<IfcParameterizedProfileDef,1>::Construct ) +, SchemaEntry("ifccshapeprofiledef",&STEP::ObjectHelper<IfcCShapeProfileDef,6>::Construct ) +, SchemaEntry("ifcfeatureelement",&STEP::ObjectHelper<IfcFeatureElement,0>::Construct ) +, SchemaEntry("ifcfeatureelementsubtraction",&STEP::ObjectHelper<IfcFeatureElementSubtraction,0>::Construct ) +, SchemaEntry("ifcedgefeature",&STEP::ObjectHelper<IfcEdgeFeature,1>::Construct ) +, SchemaEntry("ifcchamferedgefeature",&STEP::ObjectHelper<IfcChamferEdgeFeature,2>::Construct ) +, SchemaEntry("ifcbuildingelement",&STEP::ObjectHelper<IfcBuildingElement,0>::Construct ) +, SchemaEntry("ifccolumn",&STEP::ObjectHelper<IfcColumn,0>::Construct ) +, SchemaEntry("ifcpropertyreferencevalue",&STEP::ObjectHelper<IfcPropertyReferenceValue,2>::Construct ) +, SchemaEntry("ifcmaterialclassificationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcelectricmotortype",&STEP::ObjectHelper<IfcElectricMotorType,1>::Construct ) +, SchemaEntry("ifcspatialstructureelementtype",&STEP::ObjectHelper<IfcSpatialStructureElementType,0>::Construct ) +, SchemaEntry("ifcspacetype",&STEP::ObjectHelper<IfcSpaceType,1>::Construct ) +, SchemaEntry("ifcexternalreference",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcexternallydefinedhatchstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccolumntype",&STEP::ObjectHelper<IfcColumnType,1>::Construct ) +, SchemaEntry("ifccranerailashapeprofiledef",&STEP::ObjectHelper<IfcCraneRailAShapeProfileDef,12>::Construct ) +, SchemaEntry("ifccondensertype",&STEP::ObjectHelper<IfcCondenserType,1>::Construct ) , SchemaEntry("ifcrelconnectselements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcrelconnectswithrealizingelements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconstraintclassificationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcannotation",&STEP::ObjectHelper<IfcAnnotation,0>::Construct ) -, SchemaEntry("ifcplate",&STEP::ObjectHelper<IfcPlate,0>::Construct ) -, SchemaEntry("ifcsolidmodel",&STEP::ObjectHelper<IfcSolidModel,0>::Construct ) -, SchemaEntry("ifcmanifoldsolidbrep",&STEP::ObjectHelper<IfcManifoldSolidBrep,1>::Construct ) -, SchemaEntry("ifcpredefinedcurvefont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcboundarycondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcboundaryfacecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcflowstoragedevicetype",&STEP::ObjectHelper<IfcFlowStorageDeviceType,0>::Construct ) -, SchemaEntry("ifcstructuralitem",&STEP::ObjectHelper<IfcStructuralItem,0>::Construct ) -, SchemaEntry("ifcstructuralmember",&STEP::ObjectHelper<IfcStructuralMember,0>::Construct ) -, SchemaEntry("ifcstructuralcurvemember",&STEP::ObjectHelper<IfcStructuralCurveMember,1>::Construct ) -, SchemaEntry("ifcstructuralconnection",&STEP::ObjectHelper<IfcStructuralConnection,1>::Construct ) -, SchemaEntry("ifcstructuralsurfaceconnection",&STEP::ObjectHelper<IfcStructuralSurfaceConnection,0>::Construct ) -, SchemaEntry("ifccoiltype",&STEP::ObjectHelper<IfcCoilType,1>::Construct ) -, SchemaEntry("ifcductfittingtype",&STEP::ObjectHelper<IfcDuctFittingType,1>::Construct ) -, SchemaEntry("ifcstyleditem",&STEP::ObjectHelper<IfcStyledItem,3>::Construct ) -, SchemaEntry("ifcannotationoccurrence",&STEP::ObjectHelper<IfcAnnotationOccurrence,0>::Construct ) -, SchemaEntry("ifcannotationcurveoccurrence",&STEP::ObjectHelper<IfcAnnotationCurveOccurrence,0>::Construct ) -, SchemaEntry("ifcdimensioncurve",&STEP::ObjectHelper<IfcDimensionCurve,0>::Construct ) -, SchemaEntry("ifcboundedcurve",&STEP::ObjectHelper<IfcBoundedCurve,0>::Construct ) -, SchemaEntry("ifcaxis1placement",&STEP::ObjectHelper<IfcAxis1Placement,1>::Construct ) -, SchemaEntry("ifclightintensitydistribution",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpredefinedsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralpointaction",&STEP::ObjectHelper<IfcStructuralPointAction,0>::Construct ) -, SchemaEntry("ifcspatialstructureelement",&STEP::ObjectHelper<IfcSpatialStructureElement,2>::Construct ) -, SchemaEntry("ifcspace",&STEP::ObjectHelper<IfcSpace,2>::Construct ) -, SchemaEntry("ifccontextdependentunit",&STEP::ObjectHelper<IfcContextDependentUnit,1>::Construct ) -, SchemaEntry("ifcvirtualgridintersection",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassociates",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassociatesclassification",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccoolingtowertype",&STEP::ObjectHelper<IfcCoolingTowerType,1>::Construct ) -, SchemaEntry("ifcmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcgeneralmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcfacetedbrepwithvoids",&STEP::ObjectHelper<IfcFacetedBrepWithVoids,1>::Construct ) -, SchemaEntry("ifcprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcgeneralprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcvalvetype",&STEP::ObjectHelper<IfcValveType,1>::Construct ) -, SchemaEntry("ifcsystemfurnitureelementtype",&STEP::ObjectHelper<IfcSystemFurnitureElementType,0>::Construct ) -, SchemaEntry("ifcdiscreteaccessory",&STEP::ObjectHelper<IfcDiscreteAccessory,0>::Construct ) -, SchemaEntry("ifcperson",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcbuildingelementtype",&STEP::ObjectHelper<IfcBuildingElementType,0>::Construct ) -, SchemaEntry("ifcrailingtype",&STEP::ObjectHelper<IfcRailingType,1>::Construct ) -, SchemaEntry("ifcgasterminaltype",&STEP::ObjectHelper<IfcGasTerminalType,1>::Construct ) -, SchemaEntry("ifctimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcirregulartimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcspaceprogram",&STEP::ObjectHelper<IfcSpaceProgram,5>::Construct ) -, SchemaEntry("ifccovering",&STEP::ObjectHelper<IfcCovering,1>::Construct ) -, SchemaEntry("ifcshapeaspect",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccircleprofiledef",&STEP::ObjectHelper<IfcCircleProfileDef,1>::Construct ) +, SchemaEntry("ifccirclehollowprofiledef",&STEP::ObjectHelper<IfcCircleHollowProfileDef,1>::Construct ) +, SchemaEntry("ifcorganizationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcplacement",&STEP::ObjectHelper<IfcPlacement,1>::Construct ) +, SchemaEntry("ifcaxis2placement3d",&STEP::ObjectHelper<IfcAxis2Placement3D,2>::Construct ) , SchemaEntry("ifcpresentationstyle",&STEP::ObjectHelper<IfcPresentationStyle,1>::Construct ) -, SchemaEntry("ifcclassificationitemrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcelectricheatertype",&STEP::ObjectHelper<IfcElectricHeaterType,1>::Construct ) -, SchemaEntry("ifcbuildingstorey",&STEP::ObjectHelper<IfcBuildingStorey,1>::Construct ) -, SchemaEntry("ifcvertex",&STEP::ObjectHelper<IfcVertex,0>::Construct ) -, SchemaEntry("ifcvertexpoint",&STEP::ObjectHelper<IfcVertexPoint,1>::Construct ) +, SchemaEntry("ifccurvestyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcequipmentelement",&STEP::ObjectHelper<IfcEquipmentElement,0>::Construct ) +, SchemaEntry("ifccompositecurvesegment",&STEP::ObjectHelper<IfcCompositeCurveSegment,3>::Construct ) +, SchemaEntry("ifcrectangleprofiledef",&STEP::ObjectHelper<IfcRectangleProfileDef,2>::Construct ) +, SchemaEntry("ifcphysicalquantity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcphysicalcomplexquantity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelassociateslibrary",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelsequence",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcbuildingelementproxy",&STEP::ObjectHelper<IfcBuildingElementProxy,1>::Construct ) +, SchemaEntry("ifcdistributioncontrolelementtype",&STEP::ObjectHelper<IfcDistributionControlElementType,0>::Construct ) , SchemaEntry("ifcflowinstrumenttype",&STEP::ObjectHelper<IfcFlowInstrumentType,1>::Construct ) -, SchemaEntry("ifcparameterizedprofiledef",&STEP::ObjectHelper<IfcParameterizedProfileDef,1>::Construct ) -, SchemaEntry("ifcushapeprofiledef",&STEP::ObjectHelper<IfcUShapeProfileDef,8>::Construct ) -, SchemaEntry("ifcramp",&STEP::ObjectHelper<IfcRamp,1>::Construct ) -, SchemaEntry("ifcfillareastyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccompositecurve",&STEP::ObjectHelper<IfcCompositeCurve,2>::Construct ) -, SchemaEntry("ifcrelservicesbuildings",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralcurvemembervarying",&STEP::ObjectHelper<IfcStructuralCurveMemberVarying,0>::Construct ) -, SchemaEntry("ifcrelreferencedinspatialstructure",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrampflighttype",&STEP::ObjectHelper<IfcRampFlightType,1>::Construct ) , SchemaEntry("ifcdraughtingcallout",&STEP::ObjectHelper<IfcDraughtingCallout,1>::Construct ) , SchemaEntry("ifcdimensioncurvedirectedcallout",&STEP::ObjectHelper<IfcDimensionCurveDirectedCallout,0>::Construct ) -, SchemaEntry("ifcradiusdimension",&STEP::ObjectHelper<IfcRadiusDimension,0>::Construct ) -, SchemaEntry("ifcedgefeature",&STEP::ObjectHelper<IfcEdgeFeature,1>::Construct ) -, SchemaEntry("ifcsweptareasolid",&STEP::ObjectHelper<IfcSweptAreaSolid,2>::Construct ) -, SchemaEntry("ifcextrudedareasolid",&STEP::ObjectHelper<IfcExtrudedAreaSolid,2>::Construct ) -, SchemaEntry("ifcquantitycount",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcannotationtextoccurrence",&STEP::ObjectHelper<IfcAnnotationTextOccurrence,0>::Construct ) -, SchemaEntry("ifcreferencesvaluedocument",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstair",&STEP::ObjectHelper<IfcStair,1>::Construct ) -, SchemaEntry("ifcsymbolstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcfillareastyletilesymbolwithstyle",&STEP::ObjectHelper<IfcFillAreaStyleTileSymbolWithStyle,1>::Construct ) -, SchemaEntry("ifcannotationsymboloccurrence",&STEP::ObjectHelper<IfcAnnotationSymbolOccurrence,0>::Construct ) -, SchemaEntry("ifcterminatorsymbol",&STEP::ObjectHelper<IfcTerminatorSymbol,1>::Construct ) -, SchemaEntry("ifcdimensioncurveterminator",&STEP::ObjectHelper<IfcDimensionCurveTerminator,1>::Construct ) -, SchemaEntry("ifcrectangleprofiledef",&STEP::ObjectHelper<IfcRectangleProfileDef,2>::Construct ) -, SchemaEntry("ifcrectanglehollowprofiledef",&STEP::ObjectHelper<IfcRectangleHollowProfileDef,3>::Construct ) -, SchemaEntry("ifcrelassociateslibrary",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifclocalplacement",&STEP::ObjectHelper<IfcLocalPlacement,2>::Construct ) -, SchemaEntry("ifcopticalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcservicelifefactor",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassignstasks",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctask",&STEP::ObjectHelper<IfcTask,5>::Construct ) -, SchemaEntry("ifcannotationfillareaoccurrence",&STEP::ObjectHelper<IfcAnnotationFillAreaOccurrence,2>::Construct ) -, SchemaEntry("ifcface",&STEP::ObjectHelper<IfcFace,1>::Construct ) -, SchemaEntry("ifcflowsegmenttype",&STEP::ObjectHelper<IfcFlowSegmentType,0>::Construct ) -, SchemaEntry("ifcductsegmenttype",&STEP::ObjectHelper<IfcDuctSegmentType,1>::Construct ) -, SchemaEntry("ifcpropertyenumeration",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconstructionresource",&STEP::ObjectHelper<IfcConstructionResource,4>::Construct ) -, SchemaEntry("ifcconstructionequipmentresource",&STEP::ObjectHelper<IfcConstructionEquipmentResource,0>::Construct ) -, SchemaEntry("ifcsanitaryterminaltype",&STEP::ObjectHelper<IfcSanitaryTerminalType,1>::Construct ) -, SchemaEntry("ifcpredefineddimensionsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcorganization",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccircleprofiledef",&STEP::ObjectHelper<IfcCircleProfileDef,1>::Construct ) -, SchemaEntry("ifcstructuralreaction",&STEP::ObjectHelper<IfcStructuralReaction,0>::Construct ) -, SchemaEntry("ifcstructuralpointreaction",&STEP::ObjectHelper<IfcStructuralPointReaction,0>::Construct ) -, SchemaEntry("ifcrailing",&STEP::ObjectHelper<IfcRailing,1>::Construct ) -, SchemaEntry("ifctextliteral",&STEP::ObjectHelper<IfcTextLiteral,3>::Construct ) -, SchemaEntry("ifccartesiantransformationoperator",&STEP::ObjectHelper<IfcCartesianTransformationOperator,4>::Construct ) -, SchemaEntry("ifccostvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctextstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifclineardimension",&STEP::ObjectHelper<IfcLinearDimension,0>::Construct ) -, SchemaEntry("ifcdampertype",&STEP::ObjectHelper<IfcDamperType,1>::Construct ) -, SchemaEntry("ifcsiunit",&STEP::ObjectHelper<IfcSIUnit,2>::Construct ) -, SchemaEntry("ifcsurfacestylelighting",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcmeasurewithunit",&STEP::ObjectHelper<IfcMeasureWithUnit,2>::Construct ) -, SchemaEntry("ifcmateriallayerset",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdistributionelement",&STEP::ObjectHelper<IfcDistributionElement,0>::Construct ) -, SchemaEntry("ifcdistributioncontrolelement",&STEP::ObjectHelper<IfcDistributionControlElement,1>::Construct ) -, SchemaEntry("ifctransformertype",&STEP::ObjectHelper<IfcTransformerType,1>::Construct ) -, SchemaEntry("ifclaborresource",&STEP::ObjectHelper<IfcLaborResource,1>::Construct ) -, SchemaEntry("ifcderivedprofiledef",&STEP::ObjectHelper<IfcDerivedProfileDef,3>::Construct ) -, SchemaEntry("ifcrelconnectsstructuralmember",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelconnectswitheccentricity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcfurniturestandard",&STEP::ObjectHelper<IfcFurnitureStandard,0>::Construct ) -, SchemaEntry("ifcstairflighttype",&STEP::ObjectHelper<IfcStairFlightType,1>::Construct ) -, SchemaEntry("ifcworkcontrol",&STEP::ObjectHelper<IfcWorkControl,10>::Construct ) -, SchemaEntry("ifcworkplan",&STEP::ObjectHelper<IfcWorkPlan,0>::Construct ) -, SchemaEntry("ifcreldefines",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcreldefinesbyproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccondition",&STEP::ObjectHelper<IfcCondition,0>::Construct ) -, SchemaEntry("ifcgridaxis",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelvoidselement",&STEP::ObjectHelper<IfcRelVoidsElement,2>::Construct ) -, SchemaEntry("ifcwindow",&STEP::ObjectHelper<IfcWindow,2>::Construct ) -, SchemaEntry("ifcrelflowcontrolelements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelconnectsporttoelement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcprotectivedevicetype",&STEP::ObjectHelper<IfcProtectiveDeviceType,1>::Construct ) -, SchemaEntry("ifcjunctionboxtype",&STEP::ObjectHelper<IfcJunctionBoxType,1>::Construct ) -, SchemaEntry("ifcstructuralanalysismodel",&STEP::ObjectHelper<IfcStructuralAnalysisModel,4>::Construct ) -, SchemaEntry("ifcaxis2placement2d",&STEP::ObjectHelper<IfcAxis2Placement2D,1>::Construct ) -, SchemaEntry("ifcspacetype",&STEP::ObjectHelper<IfcSpaceType,1>::Construct ) -, SchemaEntry("ifcellipseprofiledef",&STEP::ObjectHelper<IfcEllipseProfileDef,2>::Construct ) -, SchemaEntry("ifcdistributionflowelement",&STEP::ObjectHelper<IfcDistributionFlowElement,0>::Construct ) -, SchemaEntry("ifcflowmovingdevice",&STEP::ObjectHelper<IfcFlowMovingDevice,0>::Construct ) -, SchemaEntry("ifcsurfacestylewithtextures",&STEP::ObjectHelper<IfcSurfaceStyleWithTextures,1>::Construct ) -, SchemaEntry("ifcgeometricset",&STEP::ObjectHelper<IfcGeometricSet,1>::Construct ) -, SchemaEntry("ifcmechanicalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcmechanicalconcretematerialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcribplateprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdocumentinformationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcelementassembly",&STEP::ObjectHelper<IfcElementAssembly,2>::Construct ) +, SchemaEntry("ifcdraughtingcalloutrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccsgprimitive3d",&STEP::ObjectHelper<IfcCsgPrimitive3D,1>::Construct ) +, SchemaEntry("ifcrightcircularcone",&STEP::ObjectHelper<IfcRightCircularCone,2>::Construct ) +, SchemaEntry("ifcexternallydefinedsurfacestyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcprojectorder",&STEP::ObjectHelper<IfcProjectOrder,3>::Construct ) -, SchemaEntry("ifcbsplinecurve",&STEP::ObjectHelper<IfcBSplineCurve,5>::Construct ) -, SchemaEntry("ifcbeziercurve",&STEP::ObjectHelper<IfcBezierCurve,0>::Construct ) -, SchemaEntry("ifcstructuralpointconnection",&STEP::ObjectHelper<IfcStructuralPointConnection,0>::Construct ) -, SchemaEntry("ifcflowcontroller",&STEP::ObjectHelper<IfcFlowController,0>::Construct ) -, SchemaEntry("ifcelectricdistributionpoint",&STEP::ObjectHelper<IfcElectricDistributionPoint,2>::Construct ) -, SchemaEntry("ifcsite",&STEP::ObjectHelper<IfcSite,5>::Construct ) +, SchemaEntry("ifcpropertyconstraintrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifclshapeprofiledef",&STEP::ObjectHelper<IfcLShapeProfileDef,8>::Construct ) +, SchemaEntry("ifcangulardimension",&STEP::ObjectHelper<IfcAngularDimension,0>::Construct ) +, SchemaEntry("ifctextstylefordefinedfont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifclocalplacement",&STEP::ObjectHelper<IfcLocalPlacement,2>::Construct ) +, SchemaEntry("ifcsweptareasolid",&STEP::ObjectHelper<IfcSweptAreaSolid,2>::Construct ) +, SchemaEntry("ifcrevolvedareasolid",&STEP::ObjectHelper<IfcRevolvedAreaSolid,2>::Construct ) +, SchemaEntry("ifcstructuralsurfaceconnection",&STEP::ObjectHelper<IfcStructuralSurfaceConnection,0>::Construct ) +, SchemaEntry("ifcradiusdimension",&STEP::ObjectHelper<IfcRadiusDimension,0>::Construct ) +, SchemaEntry("ifcsweptdisksolid",&STEP::ObjectHelper<IfcSweptDiskSolid,5>::Construct ) +, SchemaEntry("ifchalfspacesolid",&STEP::ObjectHelper<IfcHalfSpaceSolid,2>::Construct ) +, SchemaEntry("ifcpolygonalboundedhalfspace",&STEP::ObjectHelper<IfcPolygonalBoundedHalfSpace,2>::Construct ) +, SchemaEntry("ifctimeseriesschedule",&STEP::ObjectHelper<IfcTimeSeriesSchedule,3>::Construct ) +, SchemaEntry("ifcdimensioncalloutrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccooledbeamtype",&STEP::ObjectHelper<IfcCooledBeamType,1>::Construct ) +, SchemaEntry("ifcproject",&STEP::ObjectHelper<IfcProject,4>::Construct ) +, SchemaEntry("ifcapprovalrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcevaporatortype",&STEP::ObjectHelper<IfcEvaporatorType,1>::Construct ) +, SchemaEntry("ifclaborresource",&STEP::ObjectHelper<IfcLaborResource,1>::Construct ) +, SchemaEntry("ifcstructuralloadsingledisplacementdistortion",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpropertyboundedvalue",&STEP::ObjectHelper<IfcPropertyBoundedValue,3>::Construct ) +, SchemaEntry("ifcrampflighttype",&STEP::ObjectHelper<IfcRampFlightType,1>::Construct ) +, SchemaEntry("ifcmember",&STEP::ObjectHelper<IfcMember,0>::Construct ) +, SchemaEntry("ifcstructuralloadplanarforce",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctubebundletype",&STEP::ObjectHelper<IfcTubeBundleType,1>::Construct ) +, SchemaEntry("ifcvalvetype",&STEP::ObjectHelper<IfcValveType,1>::Construct ) +, SchemaEntry("ifcexternallydefinedtextfont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctrimmedcurve",&STEP::ObjectHelper<IfcTrimmedCurve,5>::Construct ) +, SchemaEntry("ifcreldefines",&STEP::ObjectHelper<IfcRelDefines,1>::Construct ) +, SchemaEntry("ifcreldefinesbyproperties",&STEP::ObjectHelper<IfcRelDefinesByProperties,1>::Construct ) +, SchemaEntry("ifcrelassignstocontrol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcactor",&STEP::ObjectHelper<IfcActor,1>::Construct ) +, SchemaEntry("ifcoccupant",&STEP::ObjectHelper<IfcOccupant,1>::Construct ) +, SchemaEntry("ifchumidifiertype",&STEP::ObjectHelper<IfcHumidifierType,1>::Construct ) +, SchemaEntry("ifcarbitraryopenprofiledef",&STEP::ObjectHelper<IfcArbitraryOpenProfileDef,1>::Construct ) +, SchemaEntry("ifcrelassignstoprojectorder",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpermit",&STEP::ObjectHelper<IfcPermit,1>::Construct ) , SchemaEntry("ifcoffsetcurve3d",&STEP::ObjectHelper<IfcOffsetCurve3D,4>::Construct ) -, SchemaEntry("ifcpropertyset",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconnectionsurfacegeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifclightsource",&STEP::ObjectHelper<IfcLightSource,4>::Construct ) +, SchemaEntry("ifclightsourcepositional",&STEP::ObjectHelper<IfcLightSourcePositional,5>::Construct ) +, SchemaEntry("ifcsurfacetexture",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcblobtexture",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccompositeprofiledef",&STEP::ObjectHelper<IfcCompositeProfileDef,2>::Construct ) +, SchemaEntry("ifcdocumentinformation",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsurfacestylelighting",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcphysicalsimplequantity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcquantityarea",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcclassificationnotation",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcramp",&STEP::ObjectHelper<IfcRamp,1>::Construct ) +, SchemaEntry("ifcpredefineditem",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpredefinedcurvefont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpredefinedcolour",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccurrencyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowmovingdevice",&STEP::ObjectHelper<IfcFlowMovingDevice,0>::Construct ) +, SchemaEntry("ifcspaceheatertype",&STEP::ObjectHelper<IfcSpaceHeaterType,1>::Construct ) +, SchemaEntry("ifclamptype",&STEP::ObjectHelper<IfcLampType,1>::Construct ) +, SchemaEntry("ifcbuildingelementcomponent",&STEP::ObjectHelper<IfcBuildingElementComponent,0>::Construct ) +, SchemaEntry("ifcreinforcingelement",&STEP::ObjectHelper<IfcReinforcingElement,1>::Construct ) +, SchemaEntry("ifcreinforcingbar",&STEP::ObjectHelper<IfcReinforcingBar,5>::Construct ) +, SchemaEntry("ifcelectricheatertype",&STEP::ObjectHelper<IfcElectricHeaterType,1>::Construct ) +, SchemaEntry("ifctshapeprofiledef",&STEP::ObjectHelper<IfcTShapeProfileDef,10>::Construct ) +, SchemaEntry("ifcconstraint",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcobjective",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralactivity",&STEP::ObjectHelper<IfcStructuralActivity,2>::Construct ) +, SchemaEntry("ifcstructuralaction",&STEP::ObjectHelper<IfcStructuralAction,2>::Construct ) +, SchemaEntry("ifctexturecoordinate",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctexturemap",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcmonetaryunit",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcquantitytime",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctablerow",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifclightdistributiondata",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcductfittingtype",&STEP::ObjectHelper<IfcDuctFittingType,1>::Construct ) +, SchemaEntry("ifccartesiantransformationoperator2d",&STEP::ObjectHelper<IfcCartesianTransformationOperator2D,0>::Construct ) +, SchemaEntry("ifccartesiantransformationoperator2dnonuniform",&STEP::ObjectHelper<IfcCartesianTransformationOperator2DnonUniform,1>::Construct ) +, SchemaEntry("ifcclassificationnotationfacet",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelassociatesapproval",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdraughtingpredefinedcurvefont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralloadsingleforce",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralloadsingleforcewarping",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccurvestylefontandscaling",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcvirtualelement",&STEP::ObjectHelper<IfcVirtualElement,0>::Construct ) -, SchemaEntry("ifcconstructionproductresource",&STEP::ObjectHelper<IfcConstructionProductResource,0>::Construct ) -, SchemaEntry("ifcwaterproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsurfacecurvesweptareasolid",&STEP::ObjectHelper<IfcSurfaceCurveSweptAreaSolid,4>::Construct ) -, SchemaEntry("ifcpermeablecoveringproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccartesiantransformationoperator3d",&STEP::ObjectHelper<IfcCartesianTransformationOperator3D,1>::Construct ) -, SchemaEntry("ifccartesiantransformationoperator3dnonuniform",&STEP::ObjectHelper<IfcCartesianTransformationOperator3DnonUniform,2>::Construct ) -, SchemaEntry("ifccrewresource",&STEP::ObjectHelper<IfcCrewResource,0>::Construct ) -, SchemaEntry("ifcstructuralsurfacemember",&STEP::ObjectHelper<IfcStructuralSurfaceMember,2>::Construct ) -, SchemaEntry("ifc2dcompositecurve",&STEP::ObjectHelper<Ifc2DCompositeCurve,0>::Construct ) -, SchemaEntry("ifcrepresentationcontext",&STEP::ObjectHelper<IfcRepresentationContext,2>::Construct ) -, SchemaEntry("ifcgeometricrepresentationcontext",&STEP::ObjectHelper<IfcGeometricRepresentationContext,4>::Construct ) -, SchemaEntry("ifcflowtreatmentdevice",&STEP::ObjectHelper<IfcFlowTreatmentDevice,0>::Construct ) -, SchemaEntry("ifctextstylefordefinedfont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcrightcircularcylinder",&STEP::ObjectHelper<IfcRightCircularCylinder,2>::Construct ) -, SchemaEntry("ifcwasteterminaltype",&STEP::ObjectHelper<IfcWasteTerminalType,1>::Construct ) -, SchemaEntry("ifcspacethermalloadproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconstraintrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcbuildingelementcomponent",&STEP::ObjectHelper<IfcBuildingElementComponent,0>::Construct ) -, SchemaEntry("ifcbuildingelementpart",&STEP::ObjectHelper<IfcBuildingElementPart,0>::Construct ) -, SchemaEntry("ifcwall",&STEP::ObjectHelper<IfcWall,0>::Construct ) -, SchemaEntry("ifcwallstandardcase",&STEP::ObjectHelper<IfcWallStandardCase,0>::Construct ) -, SchemaEntry("ifcapprovalactorrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcoutlettype",&STEP::ObjectHelper<IfcOutletType,1>::Construct ) +, SchemaEntry("ifcreldecomposes",&STEP::ObjectHelper<IfcRelDecomposes,2>::Construct ) +, SchemaEntry("ifcrelnests",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccovering",&STEP::ObjectHelper<IfcCovering,1>::Construct ) +, SchemaEntry("ifcexternallydefinedsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcirregulartimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpolyline",&STEP::ObjectHelper<IfcPolyline,1>::Construct ) , SchemaEntry("ifcpath",&STEP::ObjectHelper<IfcPath,1>::Construct ) -, SchemaEntry("ifcdefinedsymbol",&STEP::ObjectHelper<IfcDefinedSymbol,2>::Construct ) -, SchemaEntry("ifcstructuralsurfacemembervarying",&STEP::ObjectHelper<IfcStructuralSurfaceMemberVarying,2>::Construct ) -, SchemaEntry("ifcpoint",&STEP::ObjectHelper<IfcPoint,0>::Construct ) -, SchemaEntry("ifcsurfaceofrevolution",&STEP::ObjectHelper<IfcSurfaceOfRevolution,1>::Construct ) -, SchemaEntry("ifcflowterminal",&STEP::ObjectHelper<IfcFlowTerminal,0>::Construct ) -, SchemaEntry("ifcfurnishingelement",&STEP::ObjectHelper<IfcFurnishingElement,0>::Construct ) -, SchemaEntry("ifccurvestylefont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsurfacestyleshading",&STEP::ObjectHelper<IfcSurfaceStyleShading,1>::Construct ) -, SchemaEntry("ifcsurfacestylerendering",&STEP::ObjectHelper<IfcSurfaceStyleRendering,8>::Construct ) -, SchemaEntry("ifccoordinateduniversaltimeoffset",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralloadsingledisplacement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccirclehollowprofiledef",&STEP::ObjectHelper<IfcCircleHollowProfileDef,1>::Construct ) +, SchemaEntry("ifcelementcomponent",&STEP::ObjectHelper<IfcElementComponent,0>::Construct ) +, SchemaEntry("ifcfastener",&STEP::ObjectHelper<IfcFastener,0>::Construct ) +, SchemaEntry("ifcmappeditem",&STEP::ObjectHelper<IfcMappedItem,2>::Construct ) +, SchemaEntry("ifcmetric",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdocumentreference",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsectionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrectangularpyramid",&STEP::ObjectHelper<IfcRectangularPyramid,3>::Construct ) +, SchemaEntry("ifcrelreferencedinspatialstructure",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccrewresource",&STEP::ObjectHelper<IfcCrewResource,0>::Construct ) +, SchemaEntry("ifcnamedunit",&STEP::ObjectHelper<IfcNamedUnit,2>::Construct ) +, SchemaEntry("ifccontextdependentunit",&STEP::ObjectHelper<IfcContextDependentUnit,1>::Construct ) +, SchemaEntry("ifcunitaryequipmenttype",&STEP::ObjectHelper<IfcUnitaryEquipmentType,1>::Construct ) +, SchemaEntry("ifcroof",&STEP::ObjectHelper<IfcRoof,1>::Construct ) +, SchemaEntry("ifcrelassignstasks",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralmember",&STEP::ObjectHelper<IfcStructuralMember,0>::Construct ) +, SchemaEntry("ifcrelconnectsports",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstylemodel",&STEP::ObjectHelper<IfcStyleModel,0>::Construct ) +, SchemaEntry("ifcstyledrepresentation",&STEP::ObjectHelper<IfcStyledRepresentation,0>::Construct ) +, SchemaEntry("ifcspatialstructureelement",&STEP::ObjectHelper<IfcSpatialStructureElement,2>::Construct ) +, SchemaEntry("ifcbuilding",&STEP::ObjectHelper<IfcBuilding,3>::Construct ) +, SchemaEntry("ifcconnectedfaceset",&STEP::ObjectHelper<IfcConnectedFaceSet,1>::Construct ) +, SchemaEntry("ifcopenshell",&STEP::ObjectHelper<IfcOpenShell,0>::Construct ) +, SchemaEntry("ifcfacetedbrep",&STEP::ObjectHelper<IfcFacetedBrep,0>::Construct ) +, SchemaEntry("ifclocaltime",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcmechanicalconcretematerialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcconic",&STEP::ObjectHelper<IfcConic,1>::Construct ) +, SchemaEntry("ifccoveringtype",&STEP::ObjectHelper<IfcCoveringType,1>::Construct ) +, SchemaEntry("ifcroundedrectangleprofiledef",&STEP::ObjectHelper<IfcRoundedRectangleProfileDef,1>::Construct ) +, SchemaEntry("ifcairterminaltype",&STEP::ObjectHelper<IfcAirTerminalType,1>::Construct ) , SchemaEntry("ifcflowmovingdevicetype",&STEP::ObjectHelper<IfcFlowMovingDeviceType,0>::Construct ) -, SchemaEntry("ifcfantype",&STEP::ObjectHelper<IfcFanType,1>::Construct ) -, SchemaEntry("ifcstructuralplanaractionvarying",&STEP::ObjectHelper<IfcStructuralPlanarActionVarying,2>::Construct ) -, SchemaEntry("ifcproductrepresentation",&STEP::ObjectHelper<IfcProductRepresentation,3>::Construct ) -, SchemaEntry("ifcreldefinesbytype",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccompressortype",&STEP::ObjectHelper<IfcCompressorType,1>::Construct ) +, SchemaEntry("ifcwindowpanelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpredefinedsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpredefinedterminatorsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcishapeprofiledef",&STEP::ObjectHelper<IfcIShapeProfileDef,5>::Construct ) +, SchemaEntry("ifcasymmetricishapeprofiledef",&STEP::ObjectHelper<IfcAsymmetricIShapeProfileDef,4>::Construct ) +, SchemaEntry("ifccontrollertype",&STEP::ObjectHelper<IfcControllerType,1>::Construct ) +, SchemaEntry("ifcrailing",&STEP::ObjectHelper<IfcRailing,1>::Construct ) +, SchemaEntry("ifcgroup",&STEP::ObjectHelper<IfcGroup,0>::Construct ) +, SchemaEntry("ifcasset",&STEP::ObjectHelper<IfcAsset,9>::Construct ) +, SchemaEntry("ifcmaterialdefinitionrepresentation",&STEP::ObjectHelper<IfcMaterialDefinitionRepresentation,1>::Construct ) +, SchemaEntry("ifccurvestylefontpattern",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcapprovalpropertyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrailingtype",&STEP::ObjectHelper<IfcRailingType,1>::Construct ) +, SchemaEntry("ifcwall",&STEP::ObjectHelper<IfcWall,0>::Construct ) +, SchemaEntry("ifcclassificationitem",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralpointconnection",&STEP::ObjectHelper<IfcStructuralPointConnection,0>::Construct ) +, SchemaEntry("ifcconnectiongeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcconnectionpointgeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctimeseriesvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpropertylistvalue",&STEP::ObjectHelper<IfcPropertyListValue,2>::Construct ) +, SchemaEntry("ifcfurniturestandard",&STEP::ObjectHelper<IfcFurnitureStandard,0>::Construct ) +, SchemaEntry("ifcrelschedulescostitems",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcelectricgeneratortype",&STEP::ObjectHelper<IfcElectricGeneratorType,1>::Construct ) +, SchemaEntry("ifcdoor",&STEP::ObjectHelper<IfcDoor,2>::Construct ) +, SchemaEntry("ifcstyleditem",&STEP::ObjectHelper<IfcStyledItem,3>::Construct ) +, SchemaEntry("ifcannotationoccurrence",&STEP::ObjectHelper<IfcAnnotationOccurrence,0>::Construct ) +, SchemaEntry("ifcannotationsymboloccurrence",&STEP::ObjectHelper<IfcAnnotationSymbolOccurrence,0>::Construct ) +, SchemaEntry("ifcarbitraryclosedprofiledef",&STEP::ObjectHelper<IfcArbitraryClosedProfileDef,1>::Construct ) +, SchemaEntry("ifcarbitraryprofiledefwithvoids",&STEP::ObjectHelper<IfcArbitraryProfileDefWithVoids,1>::Construct ) +, SchemaEntry("ifcline",&STEP::ObjectHelper<IfcLine,2>::Construct ) +, SchemaEntry("ifcmateriallayerset",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowsegmenttype",&STEP::ObjectHelper<IfcFlowSegmentType,0>::Construct ) +, SchemaEntry("ifcairterminalboxtype",&STEP::ObjectHelper<IfcAirTerminalBoxType,1>::Construct ) +, SchemaEntry("ifcrelconnectsstructuralmember",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpropertysinglevalue",&STEP::ObjectHelper<IfcPropertySingleValue,2>::Construct ) +, SchemaEntry("ifcalarmtype",&STEP::ObjectHelper<IfcAlarmType,1>::Construct ) +, SchemaEntry("ifcellipseprofiledef",&STEP::ObjectHelper<IfcEllipseProfileDef,2>::Construct ) +, SchemaEntry("ifcstair",&STEP::ObjectHelper<IfcStair,1>::Construct ) , SchemaEntry("ifcpredefinedtextfont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifctextstylefontmodel",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstackterminaltype",&STEP::ObjectHelper<IfcStackTerminalType,1>::Construct ) -, SchemaEntry("ifcapprovalpropertyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcexternallydefinedsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcreinforcingelement",&STEP::ObjectHelper<IfcReinforcingElement,1>::Construct ) -, SchemaEntry("ifcreinforcingmesh",&STEP::ObjectHelper<IfcReinforcingMesh,8>::Construct ) -, SchemaEntry("ifcorderaction",&STEP::ObjectHelper<IfcOrderAction,1>::Construct ) -, SchemaEntry("ifcrelcoversbldgelements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifclightsource",&STEP::ObjectHelper<IfcLightSource,4>::Construct ) -, SchemaEntry("ifclightsourcedirectional",&STEP::ObjectHelper<IfcLightSourceDirectional,1>::Construct ) -, SchemaEntry("ifcloop",&STEP::ObjectHelper<IfcLoop,0>::Construct ) -, SchemaEntry("ifcvertexloop",&STEP::ObjectHelper<IfcVertexLoop,1>::Construct ) -, SchemaEntry("ifcchamferedgefeature",&STEP::ObjectHelper<IfcChamferEdgeFeature,2>::Construct ) -, SchemaEntry("ifcwindowpanelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcclassification",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsurfacestyleshading",&STEP::ObjectHelper<IfcSurfaceStyleShading,1>::Construct ) +, SchemaEntry("ifcpumptype",&STEP::ObjectHelper<IfcPumpType,1>::Construct ) +, SchemaEntry("ifcdefinedsymbol",&STEP::ObjectHelper<IfcDefinedSymbol,2>::Construct ) +, SchemaEntry("ifcclassificationitemrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcgeneralmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcelementcomponenttype",&STEP::ObjectHelper<IfcElementComponentType,0>::Construct ) , SchemaEntry("ifcfastenertype",&STEP::ObjectHelper<IfcFastenerType,0>::Construct ) , SchemaEntry("ifcmechanicalfastenertype",&STEP::ObjectHelper<IfcMechanicalFastenerType,0>::Construct ) -, SchemaEntry("ifcscheduletimecontrol",&STEP::ObjectHelper<IfcScheduleTimeControl,18>::Construct ) -, SchemaEntry("ifcsurfacestyle",&STEP::ObjectHelper<IfcSurfaceStyle,2>::Construct ) -, SchemaEntry("ifcreinforcementbarproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcopenshell",&STEP::ObjectHelper<IfcOpenShell,0>::Construct ) -, SchemaEntry("ifclibraryreference",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsubcontractresource",&STEP::ObjectHelper<IfcSubContractResource,2>::Construct ) -, SchemaEntry("ifctimeseriesreferencerelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsweptdisksolid",&STEP::ObjectHelper<IfcSweptDiskSolid,5>::Construct ) -, SchemaEntry("ifccompositeprofiledef",&STEP::ObjectHelper<IfcCompositeProfileDef,2>::Construct ) -, SchemaEntry("ifcelectricalbaseproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpredefinedpointmarkersymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctanktype",&STEP::ObjectHelper<IfcTankType,1>::Construct ) -, SchemaEntry("ifcboundarynodecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcboundarynodeconditionwarping",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassignstogroup",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpresentationlayerassignment",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsphere",&STEP::ObjectHelper<IfcSphere,1>::Construct ) -, SchemaEntry("ifcpolyloop",&STEP::ObjectHelper<IfcPolyLoop,1>::Construct ) -, SchemaEntry("ifccablecarrierfittingtype",&STEP::ObjectHelper<IfcCableCarrierFittingType,1>::Construct ) -, SchemaEntry("ifchumidifiertype",&STEP::ObjectHelper<IfcHumidifierType,1>::Construct ) -, SchemaEntry("ifcpropertylistvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpropertyconstraintrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcperformancehistory",&STEP::ObjectHelper<IfcPerformanceHistory,1>::Construct ) -, SchemaEntry("ifcshapemodel",&STEP::ObjectHelper<IfcShapeModel,0>::Construct ) -, SchemaEntry("ifctopologyrepresentation",&STEP::ObjectHelper<IfcTopologyRepresentation,0>::Construct ) -, SchemaEntry("ifcbuilding",&STEP::ObjectHelper<IfcBuilding,3>::Construct ) -, SchemaEntry("ifcroundedrectangleprofiledef",&STEP::ObjectHelper<IfcRoundedRectangleProfileDef,1>::Construct ) -, SchemaEntry("ifcstairflight",&STEP::ObjectHelper<IfcStairFlight,4>::Construct ) -, SchemaEntry("ifcsurfacestylerefraction",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelinteractionrequirements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconstraint",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcobjective",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconnectionportgeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdistributionchamberelement",&STEP::ObjectHelper<IfcDistributionChamberElement,0>::Construct ) -, SchemaEntry("ifcpersonandorganization",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcshaperepresentation",&STEP::ObjectHelper<IfcShapeRepresentation,0>::Construct ) -, SchemaEntry("ifcrampflight",&STEP::ObjectHelper<IfcRampFlight,0>::Construct ) -, SchemaEntry("ifcbeamtype",&STEP::ObjectHelper<IfcBeamType,1>::Construct ) -, SchemaEntry("ifcreldecomposes",&STEP::ObjectHelper<IfcRelDecomposes,2>::Construct ) -, SchemaEntry("ifcroof",&STEP::ObjectHelper<IfcRoof,1>::Construct ) -, SchemaEntry("ifcfooting",&STEP::ObjectHelper<IfcFooting,1>::Construct ) -, SchemaEntry("ifcrelcoversspaces",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifclightsourceambient",&STEP::ObjectHelper<IfcLightSourceAmbient,0>::Construct ) -, SchemaEntry("ifctimeseriesvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcwindowstyle",&STEP::ObjectHelper<IfcWindowStyle,4>::Construct ) -, SchemaEntry("ifcpropertyreferencevalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpermeablecoveringproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowfitting",&STEP::ObjectHelper<IfcFlowFitting,0>::Construct ) , SchemaEntry("ifcapproval",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelconnectsstructuralelement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcbuildingelementproxytype",&STEP::ObjectHelper<IfcBuildingElementProxyType,1>::Construct ) +, SchemaEntry("ifcshapeaspect",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcconstraintclassificationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifclightsourcedirectional",&STEP::ObjectHelper<IfcLightSourceDirectional,1>::Construct ) +, SchemaEntry("ifcsurfacestyle",&STEP::ObjectHelper<IfcSurfaceStyle,2>::Construct ) +, SchemaEntry("ifcrelconnectsstructuralactivity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcrelassociatesprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcaxis2placement3d",&STEP::ObjectHelper<IfcAxis2Placement3D,2>::Construct ) -, SchemaEntry("ifcrelconnectsports",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcedgecurve",&STEP::ObjectHelper<IfcEdgeCurve,2>::Construct ) -, SchemaEntry("ifcclosedshell",&STEP::ObjectHelper<IfcClosedShell,0>::Construct ) -, SchemaEntry("ifctendonanchor",&STEP::ObjectHelper<IfcTendonAnchor,0>::Construct ) -, SchemaEntry("ifccondensertype",&STEP::ObjectHelper<IfcCondenserType,1>::Construct ) -, SchemaEntry("ifcquantitytime",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsurfacetexture",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpixeltexture",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralconnectioncondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcannotationsurface",&STEP::ObjectHelper<IfcAnnotationSurface,2>::Construct ) +, SchemaEntry("ifcfuelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowcontroller",&STEP::ObjectHelper<IfcFlowController,0>::Construct ) , SchemaEntry("ifcfailureconnectioncondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdocumentreference",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcmechanicalsteelmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpipesegmenttype",&STEP::ObjectHelper<IfcPipeSegmentType,1>::Construct ) -, SchemaEntry("ifcpointonsurface",&STEP::ObjectHelper<IfcPointOnSurface,3>::Construct ) +, SchemaEntry("ifcbuildingstorey",&STEP::ObjectHelper<IfcBuildingStorey,1>::Construct ) +, SchemaEntry("ifcworkcontrol",&STEP::ObjectHelper<IfcWorkControl,10>::Construct ) +, SchemaEntry("ifcworkschedule",&STEP::ObjectHelper<IfcWorkSchedule,0>::Construct ) , SchemaEntry("ifctable",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifclightdistributiondata",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpropertytablevalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpresentationlayerwithstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcasset",&STEP::ObjectHelper<IfcAsset,9>::Construct ) -, SchemaEntry("ifclightsourcepositional",&STEP::ObjectHelper<IfcLightSourcePositional,5>::Construct ) -, SchemaEntry("ifclibraryinformation",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctextstyletextmodel",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcprojectioncurve",&STEP::ObjectHelper<IfcProjectionCurve,0>::Construct ) -, SchemaEntry("ifcfillareastyletiles",&STEP::ObjectHelper<IfcFillAreaStyleTiles,3>::Construct ) -, SchemaEntry("ifcrelfillselement",&STEP::ObjectHelper<IfcRelFillsElement,2>::Construct ) -, SchemaEntry("ifcelectricmotortype",&STEP::ObjectHelper<IfcElectricMotorType,1>::Construct ) -, SchemaEntry("ifctendon",&STEP::ObjectHelper<IfcTendon,8>::Construct ) +, SchemaEntry("ifcductsegmenttype",&STEP::ObjectHelper<IfcDuctSegmentType,1>::Construct ) +, SchemaEntry("ifcstructuralsteelprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdraughtingpredefinedtextfont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcface",&STEP::ObjectHelper<IfcFace,1>::Construct ) +, SchemaEntry("ifcstructuralsurfacemember",&STEP::ObjectHelper<IfcStructuralSurfaceMember,2>::Construct ) +, SchemaEntry("ifcstructuralsurfacemembervarying",&STEP::ObjectHelper<IfcStructuralSurfaceMemberVarying,2>::Construct ) +, SchemaEntry("ifcfacesurface",&STEP::ObjectHelper<IfcFaceSurface,2>::Construct ) +, SchemaEntry("ifcclassification",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcmateriallist",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccostschedule",&STEP::ObjectHelper<IfcCostSchedule,8>::Construct ) +, SchemaEntry("ifccoordinateduniversaltimeoffset",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcplanarextent",&STEP::ObjectHelper<IfcPlanarExtent,2>::Construct ) +, SchemaEntry("ifcplanarbox",&STEP::ObjectHelper<IfcPlanarBox,1>::Construct ) +, SchemaEntry("ifcfillareastyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsectionreinforcementproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccolourspecification",&STEP::ObjectHelper<IfcColourSpecification,1>::Construct ) +, SchemaEntry("ifcvector",&STEP::ObjectHelper<IfcVector,2>::Construct ) +, SchemaEntry("ifcbeam",&STEP::ObjectHelper<IfcBeam,0>::Construct ) +, SchemaEntry("ifccolourrgb",&STEP::ObjectHelper<IfcColourRgb,3>::Construct ) +, SchemaEntry("ifcstructuralplanaraction",&STEP::ObjectHelper<IfcStructuralPlanarAction,1>::Construct ) +, SchemaEntry("ifcstructuralplanaractionvarying",&STEP::ObjectHelper<IfcStructuralPlanarActionVarying,2>::Construct ) +, SchemaEntry("ifcsite",&STEP::ObjectHelper<IfcSite,5>::Construct ) +, SchemaEntry("ifcdiscreteaccessorytype",&STEP::ObjectHelper<IfcDiscreteAccessoryType,0>::Construct ) +, SchemaEntry("ifcvibrationisolatortype",&STEP::ObjectHelper<IfcVibrationIsolatorType,1>::Construct ) +, SchemaEntry("ifcevaporativecoolertype",&STEP::ObjectHelper<IfcEvaporativeCoolerType,1>::Construct ) , SchemaEntry("ifcdistributionchamberelementtype",&STEP::ObjectHelper<IfcDistributionChamberElementType,1>::Construct ) +, SchemaEntry("ifcfeatureelementaddition",&STEP::ObjectHelper<IfcFeatureElementAddition,0>::Construct ) +, SchemaEntry("ifcrelassignstoresource",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructureddimensioncallout",&STEP::ObjectHelper<IfcStructuredDimensionCallout,0>::Construct ) +, SchemaEntry("ifccoolingtowertype",&STEP::ObjectHelper<IfcCoolingTowerType,1>::Construct ) +, SchemaEntry("ifccenterlineprofiledef",&STEP::ObjectHelper<IfcCenterLineProfileDef,1>::Construct ) +, SchemaEntry("ifctexturevertex",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcorganization",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcwindowstyle",&STEP::ObjectHelper<IfcWindowStyle,4>::Construct ) +, SchemaEntry("ifclightsourcegoniometric",&STEP::ObjectHelper<IfcLightSourceGoniometric,6>::Construct ) +, SchemaEntry("ifcribplateprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctransformertype",&STEP::ObjectHelper<IfcTransformerType,1>::Construct ) , SchemaEntry("ifcmembertype",&STEP::ObjectHelper<IfcMemberType,1>::Construct ) -, SchemaEntry("ifcstructurallinearaction",&STEP::ObjectHelper<IfcStructuralLinearAction,1>::Construct ) -, SchemaEntry("ifcstructurallinearactionvarying",&STEP::ObjectHelper<IfcStructuralLinearActionVarying,2>::Construct ) -, SchemaEntry("ifcproductdefinitionshape",&STEP::ObjectHelper<IfcProductDefinitionShape,0>::Construct ) -, SchemaEntry("ifcfastener",&STEP::ObjectHelper<IfcFastener,0>::Construct ) -, SchemaEntry("ifcmechanicalfastener",&STEP::ObjectHelper<IfcMechanicalFastener,2>::Construct ) -, SchemaEntry("ifcfuelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcevaporatortype",&STEP::ObjectHelper<IfcEvaporatorType,1>::Construct ) -, SchemaEntry("ifcmateriallayersetusage",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdiscreteaccessorytype",&STEP::ObjectHelper<IfcDiscreteAccessoryType,0>::Construct ) -, SchemaEntry("ifcstructuralcurveconnection",&STEP::ObjectHelper<IfcStructuralCurveConnection,0>::Construct ) -, SchemaEntry("ifcprojectionelement",&STEP::ObjectHelper<IfcProjectionElement,0>::Construct ) -, SchemaEntry("ifcimagetexture",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccoveringtype",&STEP::ObjectHelper<IfcCoveringType,1>::Construct ) -, SchemaEntry("ifcrelassociatesappliedvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpumptype",&STEP::ObjectHelper<IfcPumpType,1>::Construct ) -, SchemaEntry("ifcpile",&STEP::ObjectHelper<IfcPile,2>::Construct ) -, SchemaEntry("ifcunitassignment",&STEP::ObjectHelper<IfcUnitAssignment,1>::Construct ) -, SchemaEntry("ifcboundingbox",&STEP::ObjectHelper<IfcBoundingBox,4>::Construct ) +, SchemaEntry("ifcsurfaceoflinearextrusion",&STEP::ObjectHelper<IfcSurfaceOfLinearExtrusion,2>::Construct ) +, SchemaEntry("ifcmotorconnectiontype",&STEP::ObjectHelper<IfcMotorConnectionType,1>::Construct ) +, SchemaEntry("ifcflowtreatmentdevicetype",&STEP::ObjectHelper<IfcFlowTreatmentDeviceType,0>::Construct ) +, SchemaEntry("ifcductsilencertype",&STEP::ObjectHelper<IfcDuctSilencerType,1>::Construct ) +, SchemaEntry("ifcwindowliningproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcfurnishingelementtype",&STEP::ObjectHelper<IfcFurnishingElementType,0>::Construct ) +, SchemaEntry("ifcsystemfurnitureelementtype",&STEP::ObjectHelper<IfcSystemFurnitureElementType,0>::Construct ) +, SchemaEntry("ifcconnectionpointeccentricity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcwasteterminaltype",&STEP::ObjectHelper<IfcWasteTerminalType,1>::Construct ) +, SchemaEntry("ifcbsplinecurve",&STEP::ObjectHelper<IfcBSplineCurve,5>::Construct ) +, SchemaEntry("ifcbeziercurve",&STEP::ObjectHelper<IfcBezierCurve,0>::Construct ) +, SchemaEntry("ifcdocumentinformationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcactuatortype",&STEP::ObjectHelper<IfcActuatorType,1>::Construct ) +, SchemaEntry("ifcdistributioncontrolelement",&STEP::ObjectHelper<IfcDistributionControlElement,1>::Construct ) +, SchemaEntry("ifcannotation",&STEP::ObjectHelper<IfcAnnotation,0>::Construct ) +, SchemaEntry("ifcrelassociatesdocument",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdoorliningproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcshellbasedsurfacemodel",&STEP::ObjectHelper<IfcShellBasedSurfaceModel,1>::Construct ) -, SchemaEntry("ifcfacetedbrep",&STEP::ObjectHelper<IfcFacetedBrep,0>::Construct ) -, SchemaEntry("ifctextliteralwithextent",&STEP::ObjectHelper<IfcTextLiteralWithExtent,2>::Construct ) -, SchemaEntry("ifcapplication",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcextendedmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcelectricappliancetype",&STEP::ObjectHelper<IfcElectricApplianceType,1>::Construct ) -, SchemaEntry("ifcreloccupiesspaces",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctrapeziumprofiledef",&STEP::ObjectHelper<IfcTrapeziumProfileDef,4>::Construct ) -, SchemaEntry("ifcquantityweight",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelcontainedinspatialstructure",&STEP::ObjectHelper<IfcRelContainedInSpatialStructure,2>::Construct ) -, SchemaEntry("ifcedgeloop",&STEP::ObjectHelper<IfcEdgeLoop,1>::Construct ) -, SchemaEntry("ifcproject",&STEP::ObjectHelper<IfcProject,4>::Construct ) -, SchemaEntry("ifccartesianpoint",&STEP::ObjectHelper<IfcCartesianPoint,1>::Construct ) -, SchemaEntry("ifcmaterial",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccurveboundedplane",&STEP::ObjectHelper<IfcCurveBoundedPlane,3>::Construct ) -, SchemaEntry("ifcwalltype",&STEP::ObjectHelper<IfcWallType,1>::Construct ) +, SchemaEntry("ifcactionrequest",&STEP::ObjectHelper<IfcActionRequest,1>::Construct ) +, SchemaEntry("ifcextrudedareasolid",&STEP::ObjectHelper<IfcExtrudedAreaSolid,2>::Construct ) +, SchemaEntry("ifcsystem",&STEP::ObjectHelper<IfcSystem,0>::Construct ) , SchemaEntry("ifcfillareastylehatching",&STEP::ObjectHelper<IfcFillAreaStyleHatching,5>::Construct ) +, SchemaEntry("ifcrelvoidselement",&STEP::ObjectHelper<IfcRelVoidsElement,2>::Construct ) +, SchemaEntry("ifcrelconnectspathelements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelspaceboundary",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsurfacecurvesweptareasolid",&STEP::ObjectHelper<IfcSurfaceCurveSweptAreaSolid,4>::Construct ) +, SchemaEntry("ifccartesiantransformationoperator3dnonuniform",&STEP::ObjectHelper<IfcCartesianTransformationOperator3DnonUniform,2>::Construct ) +, SchemaEntry("ifcrelinteractionrequirements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccurtainwalltype",&STEP::ObjectHelper<IfcCurtainWallType,1>::Construct ) +, SchemaEntry("ifcquantitylength",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcequipmentstandard",&STEP::ObjectHelper<IfcEquipmentStandard,0>::Construct ) -, SchemaEntry("ifchygroscopicmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdoorpanelproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowstoragedevicetype",&STEP::ObjectHelper<IfcFlowStorageDeviceType,0>::Construct ) +, SchemaEntry("ifcvirtualgridintersection",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcdiameterdimension",&STEP::ObjectHelper<IfcDiameterDimension,0>::Construct ) -, SchemaEntry("ifcstructuralloadgroup",&STEP::ObjectHelper<IfcStructuralLoadGroup,5>::Construct ) +, SchemaEntry("ifcswitchingdevicetype",&STEP::ObjectHelper<IfcSwitchingDeviceType,1>::Construct ) +, SchemaEntry("ifcaddress",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifctelecomaddress",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcconstructionmaterialresource",&STEP::ObjectHelper<IfcConstructionMaterialResource,2>::Construct ) -, SchemaEntry("ifcblobtexture",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcirregulartimeseriesvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelaggregates",&STEP::ObjectHelper<IfcRelAggregates,0>::Construct ) -, SchemaEntry("ifcboilertype",&STEP::ObjectHelper<IfcBoilerType,1>::Construct ) +, SchemaEntry("ifcwindow",&STEP::ObjectHelper<IfcWindow,2>::Construct ) +, SchemaEntry("ifcmechanicalsteelmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowtreatmentdevice",&STEP::ObjectHelper<IfcFlowTreatmentDevice,0>::Construct ) +, SchemaEntry("ifcrelservicesbuildings",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcchillertype",&STEP::ObjectHelper<IfcChillerType,1>::Construct ) +, SchemaEntry("ifcrelassignstoproduct",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrectanglehollowprofiledef",&STEP::ObjectHelper<IfcRectangleHollowProfileDef,3>::Construct ) +, SchemaEntry("ifcenergyproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcboxedhalfspace",&STEP::ObjectHelper<IfcBoxedHalfSpace,1>::Construct ) +, SchemaEntry("ifcaxis2placement2d",&STEP::ObjectHelper<IfcAxis2Placement2D,1>::Construct ) +, SchemaEntry("ifcspaceprogram",&STEP::ObjectHelper<IfcSpaceProgram,5>::Construct ) +, SchemaEntry("ifcpoint",&STEP::ObjectHelper<IfcPoint,0>::Construct ) +, SchemaEntry("ifccartesianpoint",&STEP::ObjectHelper<IfcCartesianPoint,1>::Construct ) +, SchemaEntry("ifcboundedsurface",&STEP::ObjectHelper<IfcBoundedSurface,0>::Construct ) +, SchemaEntry("ifcloop",&STEP::ObjectHelper<IfcLoop,0>::Construct ) +, SchemaEntry("ifcpolyloop",&STEP::ObjectHelper<IfcPolyLoop,1>::Construct ) +, SchemaEntry("ifcpredefinedpointmarkersymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcterminatorsymbol",&STEP::ObjectHelper<IfcTerminatorSymbol,1>::Construct ) +, SchemaEntry("ifcdimensioncurveterminator",&STEP::ObjectHelper<IfcDimensionCurveTerminator,1>::Construct ) , SchemaEntry("ifcrelprojectselement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccolourspecification",&STEP::ObjectHelper<IfcColourSpecification,1>::Construct ) -, SchemaEntry("ifccolourrgb",&STEP::ObjectHelper<IfcColourRgb,3>::Construct ) -, SchemaEntry("ifcrelconnectsstructuralactivity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdoorstyle",&STEP::ObjectHelper<IfcDoorStyle,4>::Construct ) -, SchemaEntry("ifcstructuralloadsingledisplacementdistortion",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassignstoprocess",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcductsilencertype",&STEP::ObjectHelper<IfcDuctSilencerType,1>::Construct ) -, SchemaEntry("ifclightsourcegoniometric",&STEP::ObjectHelper<IfcLightSourceGoniometric,6>::Construct ) -, SchemaEntry("ifcactuatortype",&STEP::ObjectHelper<IfcActuatorType,1>::Construct ) +, SchemaEntry("ifctrapeziumprofiledef",&STEP::ObjectHelper<IfcTrapeziumProfileDef,4>::Construct ) +, SchemaEntry("ifcrepresentationcontext",&STEP::ObjectHelper<IfcRepresentationContext,2>::Construct ) +, SchemaEntry("ifcgeometricrepresentationcontext",&STEP::ObjectHelper<IfcGeometricRepresentationContext,4>::Construct ) +, SchemaEntry("ifctextstylewithboxcharacteristics",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccurveboundedplane",&STEP::ObjectHelper<IfcCurveBoundedPlane,3>::Construct ) +, SchemaEntry("ifcquantitycount",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctimeseriesreferencerelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralloadtemperature",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsiunit",&STEP::ObjectHelper<IfcSIUnit,2>::Construct ) +, SchemaEntry("ifcstructuralreaction",&STEP::ObjectHelper<IfcStructuralReaction,0>::Construct ) +, SchemaEntry("ifcstructuralpointreaction",&STEP::ObjectHelper<IfcStructuralPointReaction,0>::Construct ) +, SchemaEntry("ifcaxis1placement",&STEP::ObjectHelper<IfcAxis1Placement,1>::Construct ) +, SchemaEntry("ifcreinforcementdefinitionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcelectricappliancetype",&STEP::ObjectHelper<IfcElectricApplianceType,1>::Construct ) , SchemaEntry("ifcsensortype",&STEP::ObjectHelper<IfcSensorType,1>::Construct ) -, SchemaEntry("ifcairterminalboxtype",&STEP::ObjectHelper<IfcAirTerminalBoxType,1>::Construct ) -, SchemaEntry("ifcannotationsurfaceoccurrence",&STEP::ObjectHelper<IfcAnnotationSurfaceOccurrence,0>::Construct ) +, SchemaEntry("ifcfurnishingelement",&STEP::ObjectHelper<IfcFurnishingElement,0>::Construct ) +, SchemaEntry("ifcprotectivedevicetype",&STEP::ObjectHelper<IfcProtectiveDeviceType,1>::Construct ) , SchemaEntry("ifczshapeprofiledef",&STEP::ObjectHelper<IfcZShapeProfileDef,6>::Construct ) -, SchemaEntry("ifcclassificationnotation",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrationalbeziercurve",&STEP::ObjectHelper<IfcRationalBezierCurve,1>::Construct ) -, SchemaEntry("ifccartesiantransformationoperator2d",&STEP::ObjectHelper<IfcCartesianTransformationOperator2D,0>::Construct ) -, SchemaEntry("ifccartesiantransformationoperator2dnonuniform",&STEP::ObjectHelper<IfcCartesianTransformationOperator2DnonUniform,1>::Construct ) -, SchemaEntry("ifcmove",&STEP::ObjectHelper<IfcMove,3>::Construct ) -, SchemaEntry("ifcboundaryedgecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdoorliningproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccablecarriersegmenttype",&STEP::ObjectHelper<IfcCableCarrierSegmentType,1>::Construct ) +, SchemaEntry("ifcscheduletimecontrol",&STEP::ObjectHelper<IfcScheduleTimeControl,18>::Construct ) +, SchemaEntry("ifcrepresentationmap",&STEP::ObjectHelper<IfcRepresentationMap,2>::Construct ) +, SchemaEntry("ifcclosedshell",&STEP::ObjectHelper<IfcClosedShell,0>::Construct ) +, SchemaEntry("ifcbuildingelementpart",&STEP::ObjectHelper<IfcBuildingElementPart,0>::Construct ) +, SchemaEntry("ifcdraughtingpredefinedcolour",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifcpostaladdress",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelconnectspathelements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcelectricalelement",&STEP::ObjectHelper<IfcElectricalElement,0>::Construct ) -, SchemaEntry("ifcownerhistory",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralloadtemperature",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctextstylewithboxcharacteristics",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcchillertype",&STEP::ObjectHelper<IfcChillerType,1>::Construct ) -, SchemaEntry("ifcrelschedulescostitems",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcreinforcingbar",&STEP::ObjectHelper<IfcReinforcingBar,5>::Construct ) -, SchemaEntry("ifccurrencyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsoundvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccshapeprofiledef",&STEP::ObjectHelper<IfcCShapeProfileDef,6>::Construct ) -, SchemaEntry("ifcpermit",&STEP::ObjectHelper<IfcPermit,1>::Construct ) -, SchemaEntry("ifcslabtype",&STEP::ObjectHelper<IfcSlabType,1>::Construct ) -, SchemaEntry("ifcslippageconnectioncondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifclamptype",&STEP::ObjectHelper<IfcLampType,1>::Construct ) -, SchemaEntry("ifcplanarextent",&STEP::ObjectHelper<IfcPlanarExtent,2>::Construct ) -, SchemaEntry("ifcalarmtype",&STEP::ObjectHelper<IfcAlarmType,1>::Construct ) -, SchemaEntry("ifcdocumentelectronicformat",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcelectricflowstoragedevicetype",&STEP::ObjectHelper<IfcElectricFlowStorageDeviceType,1>::Construct ) -, SchemaEntry("ifcequipmentelement",&STEP::ObjectHelper<IfcEquipmentElement,0>::Construct ) +, SchemaEntry("ifcblock",&STEP::ObjectHelper<IfcBlock,3>::Construct ) , SchemaEntry("ifclightfixturetype",&STEP::ObjectHelper<IfcLightFixtureType,1>::Construct ) -, SchemaEntry("ifcmetric",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelnests",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccurtainwall",&STEP::ObjectHelper<IfcCurtainWall,0>::Construct ) -, SchemaEntry("ifcrelassociatesdocument",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccomplexproperty",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcvertexbasedtexturemap",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcslab",&STEP::ObjectHelper<IfcSlab,1>::Construct ) -, SchemaEntry("ifccurtainwalltype",&STEP::ObjectHelper<IfcCurtainWallType,1>::Construct ) -, SchemaEntry("ifcoutlettype",&STEP::ObjectHelper<IfcOutletType,1>::Construct ) -, SchemaEntry("ifccompressortype",&STEP::ObjectHelper<IfcCompressorType,1>::Construct ) -, SchemaEntry("ifccranerailashapeprofiledef",&STEP::ObjectHelper<IfcCraneRailAShapeProfileDef,12>::Construct ) -, SchemaEntry("ifcflowsegment",&STEP::ObjectHelper<IfcFlowSegment,0>::Construct ) -, SchemaEntry("ifcsectionedspine",&STEP::ObjectHelper<IfcSectionedSpine,3>::Construct ) -, SchemaEntry("ifctablerow",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdraughtingpredefinedtextfont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcelectrictimecontroltype",&STEP::ObjectHelper<IfcElectricTimeControlType,1>::Construct ) -, SchemaEntry("ifcfacesurface",&STEP::ObjectHelper<IfcFaceSurface,2>::Construct ) -, SchemaEntry("ifcmateriallist",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcmotorconnectiontype",&STEP::ObjectHelper<IfcMotorConnectionType,1>::Construct ) -, SchemaEntry("ifcflowfitting",&STEP::ObjectHelper<IfcFlowFitting,0>::Construct ) -, SchemaEntry("ifcpointoncurve",&STEP::ObjectHelper<IfcPointOnCurve,2>::Construct ) -, SchemaEntry("ifctransportelementtype",&STEP::ObjectHelper<IfcTransportElementType,1>::Construct ) -, SchemaEntry("ifcregulartimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassociatesconstraint",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcpropertyenumeratedvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcstructuralsteelprofileproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcopeningelement",&STEP::ObjectHelper<IfcOpeningElement,0>::Construct ) +, SchemaEntry("ifclightsourcespot",&STEP::ObjectHelper<IfcLightSourceSpot,4>::Construct ) +, SchemaEntry("ifctendonanchor",&STEP::ObjectHelper<IfcTendonAnchor,0>::Construct ) +, SchemaEntry("ifcsurfacestylerefraction",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcelectricflowstoragedevicetype",&STEP::ObjectHelper<IfcElectricFlowStorageDeviceType,1>::Construct ) +, SchemaEntry("ifcfluidflowproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsphere",&STEP::ObjectHelper<IfcSphere,1>::Construct ) +, SchemaEntry("ifcrelassociatesappliedvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdampertype",&STEP::ObjectHelper<IfcDamperType,1>::Construct ) +, SchemaEntry("ifcprojectorderrecord",&STEP::ObjectHelper<IfcProjectOrderRecord,2>::Construct ) +, SchemaEntry("ifcdimensionalexponents",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcreldefinesbytype",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcdistributionchamberelement",&STEP::ObjectHelper<IfcDistributionChamberElement,0>::Construct ) +, SchemaEntry("ifcmechanicalfastener",&STEP::ObjectHelper<IfcMechanicalFastener,2>::Construct ) +, SchemaEntry("ifcquantityvolume",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrectangulartrimmedsurface",&STEP::ObjectHelper<IfcRectangularTrimmedSurface,7>::Construct ) +, SchemaEntry("ifcdateandtime",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifczone",&STEP::ObjectHelper<IfcZone,0>::Construct ) +, SchemaEntry("ifcfantype",&STEP::ObjectHelper<IfcFanType,1>::Construct ) +, SchemaEntry("ifcgeometricset",&STEP::ObjectHelper<IfcGeometricSet,1>::Construct ) +, SchemaEntry("ifcfillareastyletiles",&STEP::ObjectHelper<IfcFillAreaStyleTiles,3>::Construct ) +, SchemaEntry("ifcpixeltexture",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifccablesegmenttype",&STEP::ObjectHelper<IfcCableSegmentType,1>::Construct ) -, SchemaEntry("ifcexternallydefinedhatchstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcannotationsurface",&STEP::ObjectHelper<IfcAnnotationSurface,2>::Construct ) -, SchemaEntry("ifccompositecurvesegment",&STEP::ObjectHelper<IfcCompositeCurveSegment,3>::Construct ) +, SchemaEntry("ifcreloverridesproperties",&STEP::ObjectHelper<IfcRelOverridesProperties,1>::Construct ) +, SchemaEntry("ifcmeasurewithunit",&STEP::ObjectHelper<IfcMeasureWithUnit,2>::Construct ) +, SchemaEntry("ifcslabtype",&STEP::ObjectHelper<IfcSlabType,1>::Construct ) , SchemaEntry("ifcservicelife",&STEP::ObjectHelper<IfcServiceLife,2>::Construct ) -, SchemaEntry("ifcplatetype",&STEP::ObjectHelper<IfcPlateType,1>::Construct ) -, SchemaEntry("ifccurvestyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcsectionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcvibrationisolatortype",&STEP::ObjectHelper<IfcVibrationIsolatorType,1>::Construct ) -, SchemaEntry("ifctexturemap",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctrimmedcurve",&STEP::ObjectHelper<IfcTrimmedCurve,5>::Construct ) -, SchemaEntry("ifcmappeditem",&STEP::ObjectHelper<IfcMappedItem,2>::Construct ) -, SchemaEntry("ifcmateriallayer",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdirection",&STEP::ObjectHelper<IfcDirection,1>::Construct ) -, SchemaEntry("ifcblock",&STEP::ObjectHelper<IfcBlock,3>::Construct ) -, SchemaEntry("ifcprojectorderrecord",&STEP::ObjectHelper<IfcProjectOrderRecord,2>::Construct ) -, SchemaEntry("ifcflowmetertype",&STEP::ObjectHelper<IfcFlowMeterType,1>::Construct ) -, SchemaEntry("ifccontrollertype",&STEP::ObjectHelper<IfcControllerType,1>::Construct ) -, SchemaEntry("ifcbeam",&STEP::ObjectHelper<IfcBeam,0>::Construct ) -, SchemaEntry("ifcarbitraryopenprofiledef",&STEP::ObjectHelper<IfcArbitraryOpenProfileDef,1>::Construct ) -, SchemaEntry("ifccenterlineprofiledef",&STEP::ObjectHelper<IfcCenterLineProfileDef,1>::Construct ) -, SchemaEntry("ifcstructuralloadplanarforce",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifctimeseriesschedule",&STEP::ObjectHelper<IfcTimeSeriesSchedule,3>::Construct ) -, SchemaEntry("ifcroundededgefeature",&STEP::ObjectHelper<IfcRoundedEdgeFeature,1>::Construct ) -, SchemaEntry("ifcwindowliningproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcreloverridesproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcapprovalrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcishapeprofiledef",&STEP::ObjectHelper<IfcIShapeProfileDef,5>::Construct ) -, SchemaEntry("ifcspaceheatertype",&STEP::ObjectHelper<IfcSpaceHeaterType,1>::Construct ) -, SchemaEntry("ifcexternallydefinedsurfacestyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcderivedunit",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcflowstoragedevice",&STEP::ObjectHelper<IfcFlowStorageDevice,0>::Construct ) -, SchemaEntry("ifcmaterialclassificationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcclassificationitem",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrevolvedareasolid",&STEP::ObjectHelper<IfcRevolvedAreaSolid,2>::Construct ) -, SchemaEntry("ifcconnectionpointgeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdoor",&STEP::ObjectHelper<IfcDoor,2>::Construct ) -, SchemaEntry("ifcellipse",&STEP::ObjectHelper<IfcEllipse,2>::Construct ) -, SchemaEntry("ifctubebundletype",&STEP::ObjectHelper<IfcTubeBundleType,1>::Construct ) -, SchemaEntry("ifcangulardimension",&STEP::ObjectHelper<IfcAngularDimension,0>::Construct ) -, SchemaEntry("ifcthermalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcfurnituretype",&STEP::ObjectHelper<IfcFurnitureType,1>::Construct ) +, SchemaEntry("ifccostitem",&STEP::ObjectHelper<IfcCostItem,0>::Construct ) +, SchemaEntry("ifcreinforcingmesh",&STEP::ObjectHelper<IfcReinforcingMesh,8>::Construct ) +, SchemaEntry("ifcextendedmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcactorrole",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcfacetedbrepwithvoids",&STEP::ObjectHelper<IfcFacetedBrepWithVoids,1>::Construct ) +, SchemaEntry("ifcconstraintaggregationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcgasterminaltype",&STEP::ObjectHelper<IfcGasTerminalType,1>::Construct ) +, SchemaEntry("ifcrelconnectswitheccentricity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpile",&STEP::ObjectHelper<IfcPile,2>::Construct ) +, SchemaEntry("ifcfillareastyletilesymbolwithstyle",&STEP::ObjectHelper<IfcFillAreaStyleTileSymbolWithStyle,1>::Construct ) +, SchemaEntry("ifcelectricalbaseproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcconstructionmaterialresource",&STEP::ObjectHelper<IfcConstructionMaterialResource,2>::Construct ) +, SchemaEntry("ifcannotationcurveoccurrence",&STEP::ObjectHelper<IfcAnnotationCurveOccurrence,0>::Construct ) +, SchemaEntry("ifcdimensioncurve",&STEP::ObjectHelper<IfcDimensionCurve,0>::Construct ) +, SchemaEntry("ifcgeometriccurveset",&STEP::ObjectHelper<IfcGeometricCurveSet,0>::Construct ) +, SchemaEntry("ifcrelaggregates",&STEP::ObjectHelper<IfcRelAggregates,0>::Construct ) , SchemaEntry("ifcfacebasedsurfacemodel",&STEP::ObjectHelper<IfcFaceBasedSurfaceModel,1>::Construct ) -, SchemaEntry("ifccranerailfshapeprofiledef",&STEP::ObjectHelper<IfcCraneRailFShapeProfileDef,9>::Construct ) -, SchemaEntry("ifccolumntype",&STEP::ObjectHelper<IfcColumnType,1>::Construct ) -, SchemaEntry("ifctshapeprofiledef",&STEP::ObjectHelper<IfcTShapeProfileDef,10>::Construct ) , SchemaEntry("ifcenergyconversiondevice",&STEP::ObjectHelper<IfcEnergyConversionDevice,0>::Construct ) -, SchemaEntry("ifcconnectionpointeccentricity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcreinforcementdefinitionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifccurvestylefontandscaling",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcworkschedule",&STEP::ObjectHelper<IfcWorkSchedule,0>::Construct ) -, SchemaEntry("ifcorganizationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifczone",&STEP::ObjectHelper<IfcZone,0>::Construct ) -, SchemaEntry("ifctransportelement",&STEP::ObjectHelper<IfcTransportElement,3>::Construct ) -, SchemaEntry("ifcdraughtingpredefinedcurvefont",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcgeometricrepresentationsubcontext",&STEP::ObjectHelper<IfcGeometricRepresentationSubContext,4>::Construct ) -, SchemaEntry("ifclshapeprofiledef",&STEP::ObjectHelper<IfcLShapeProfileDef,8>::Construct ) -, SchemaEntry("ifcgeometriccurveset",&STEP::ObjectHelper<IfcGeometricCurveSet,0>::Construct ) -, SchemaEntry("ifcactor",&STEP::ObjectHelper<IfcActor,1>::Construct ) -, SchemaEntry("ifcoccupant",&STEP::ObjectHelper<IfcOccupant,1>::Construct ) -, SchemaEntry("ifcphysicalcomplexquantity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcbooleanclippingresult",&STEP::ObjectHelper<IfcBooleanClippingResult,0>::Construct ) -, SchemaEntry("ifcpredefinedterminatorsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcannotationfillarea",&STEP::ObjectHelper<IfcAnnotationFillArea,2>::Construct ) -, SchemaEntry("ifcconstraintaggregationrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassociatesapproval",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassociatesmaterial",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcrelassignstoproduct",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcappliedvaluerelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifclightsourcespot",&STEP::ObjectHelper<IfcLightSourceSpot,4>::Construct ) -, SchemaEntry("ifcfiresuppressionterminaltype",&STEP::ObjectHelper<IfcFireSuppressionTerminalType,1>::Construct ) -, SchemaEntry("ifcelementquantity",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrampflight",&STEP::ObjectHelper<IfcRampFlight,0>::Construct ) +, SchemaEntry("ifcpropertyenumeration",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcvertexloop",&STEP::ObjectHelper<IfcVertexLoop,1>::Construct ) +, SchemaEntry("ifcplate",&STEP::ObjectHelper<IfcPlate,0>::Construct ) +, SchemaEntry("ifcushapeprofiledef",&STEP::ObjectHelper<IfcUShapeProfileDef,8>::Construct ) +, SchemaEntry("ifchygroscopicmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcfacebound",&STEP::ObjectHelper<IfcFaceBound,2>::Construct ) +, SchemaEntry("ifcfaceouterbound",&STEP::ObjectHelper<IfcFaceOuterBound,0>::Construct ) +, SchemaEntry("ifconedirectionrepeatfactor",&STEP::ObjectHelper<IfcOneDirectionRepeatFactor,1>::Construct ) +, SchemaEntry("ifcboilertype",&STEP::ObjectHelper<IfcBoilerType,1>::Construct ) +, SchemaEntry("ifcconstructionequipmentresource",&STEP::ObjectHelper<IfcConstructionEquipmentResource,0>::Construct ) +, SchemaEntry("ifccomplexproperty",&STEP::ObjectHelper<IfcComplexProperty,2>::Construct ) +, SchemaEntry("ifcfooting",&STEP::ObjectHelper<IfcFooting,1>::Construct ) +, SchemaEntry("ifcopticalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcconstructionproductresource",&STEP::ObjectHelper<IfcConstructionProductResource,0>::Construct ) +, SchemaEntry("ifcboundaryedgecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcderivedprofiledef",&STEP::ObjectHelper<IfcDerivedProfileDef,3>::Construct ) +, SchemaEntry("ifcpropertytablevalue",&STEP::ObjectHelper<IfcPropertyTableValue,5>::Construct ) +, SchemaEntry("ifcrelassignstogroup",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcflowmetertype",&STEP::ObjectHelper<IfcFlowMeterType,1>::Construct ) +, SchemaEntry("ifcdoorstyle",&STEP::ObjectHelper<IfcDoorStyle,4>::Construct ) +, SchemaEntry("ifcrelconnectsporttoelement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelassociatesclassification",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcunitassignment",&STEP::ObjectHelper<IfcUnitAssignment,1>::Construct ) +, SchemaEntry("ifcflowterminal",&STEP::ObjectHelper<IfcFlowTerminal,0>::Construct ) +, SchemaEntry("ifccranerailfshapeprofiledef",&STEP::ObjectHelper<IfcCraneRailFShapeProfileDef,9>::Construct ) +, SchemaEntry("ifcflowsegment",&STEP::ObjectHelper<IfcFlowSegment,0>::Construct ) +, SchemaEntry("ifcelementquantity",&STEP::ObjectHelper<IfcElementQuantity,2>::Construct ) +, SchemaEntry("ifcboundarynodecondition",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcboundarynodeconditionwarping",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccurtainwall",&STEP::ObjectHelper<IfcCurtainWall,0>::Construct ) +, SchemaEntry("ifcdiscreteaccessory",&STEP::ObjectHelper<IfcDiscreteAccessory,0>::Construct ) +, SchemaEntry("ifcgrid",&STEP::ObjectHelper<IfcGrid,3>::Construct ) +, SchemaEntry("ifcsanitaryterminaltype",&STEP::ObjectHelper<IfcSanitaryTerminalType,1>::Construct ) +, SchemaEntry("ifcsoundproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsubedge",&STEP::ObjectHelper<IfcSubedge,1>::Construct ) +, SchemaEntry("ifctextstyletextmodel",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcfiltertype",&STEP::ObjectHelper<IfcFilterType,1>::Construct ) +, SchemaEntry("ifcsymbolstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctendon",&STEP::ObjectHelper<IfcTendon,8>::Construct ) , SchemaEntry("ifcdimensionpair",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcelectricgeneratortype",&STEP::ObjectHelper<IfcElectricGeneratorType,1>::Construct ) -, SchemaEntry("ifcrelsequence",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralloadgroup",&STEP::ObjectHelper<IfcStructuralLoadGroup,5>::Construct ) +, SchemaEntry("ifcpresentationstyleassignment",&STEP::ObjectHelper<IfcPresentationStyleAssignment,1>::Construct ) +, SchemaEntry("ifcregulartimeseries",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralcurvemember",&STEP::ObjectHelper<IfcStructuralCurveMember,1>::Construct ) +, SchemaEntry("ifclightsourceambient",&STEP::ObjectHelper<IfcLightSourceAmbient,0>::Construct ) +, SchemaEntry("ifccondition",&STEP::ObjectHelper<IfcCondition,0>::Construct ) +, SchemaEntry("ifcport",&STEP::ObjectHelper<IfcPort,0>::Construct ) +, SchemaEntry("ifcspace",&STEP::ObjectHelper<IfcSpace,2>::Construct ) +, SchemaEntry("ifcheatexchangertype",&STEP::ObjectHelper<IfcHeatExchangerType,1>::Construct ) +, SchemaEntry("ifctanktype",&STEP::ObjectHelper<IfcTankType,1>::Construct ) , SchemaEntry("ifcinventory",&STEP::ObjectHelper<IfcInventory,6>::Construct ) -, SchemaEntry("ifcpolyline",&STEP::ObjectHelper<IfcPolyline,1>::Construct ) -, SchemaEntry("ifcboxedhalfspace",&STEP::ObjectHelper<IfcBoxedHalfSpace,1>::Construct ) -, SchemaEntry("ifcairterminaltype",&STEP::ObjectHelper<IfcAirTerminalType,1>::Construct ) -, SchemaEntry("ifcsectionreinforcementproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcdistributionport",&STEP::ObjectHelper<IfcDistributionPort,1>::Construct ) -, SchemaEntry("ifccostitem",&STEP::ObjectHelper<IfcCostItem,0>::Construct ) -, SchemaEntry("ifcstructureddimensioncallout",&STEP::ObjectHelper<IfcStructuredDimensionCallout,0>::Construct ) +, SchemaEntry("ifctextstyle",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcappliedvaluerelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsoundvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctransportelementtype",&STEP::ObjectHelper<IfcTransportElementType,1>::Construct ) +, SchemaEntry("ifcairtoairheatrecoverytype",&STEP::ObjectHelper<IfcAirToAirHeatRecoveryType,1>::Construct ) +, SchemaEntry("ifcstairflight",&STEP::ObjectHelper<IfcStairFlight,4>::Construct ) +, SchemaEntry("ifcelectricalelement",&STEP::ObjectHelper<IfcElectricalElement,0>::Construct ) +, SchemaEntry("ifclightintensitydistribution",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcclassificationreference",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsurfacestylewithtextures",&STEP::ObjectHelper<IfcSurfaceStyleWithTextures,1>::Construct ) +, SchemaEntry("ifcboundingbox",&STEP::ObjectHelper<IfcBoundingBox,4>::Construct ) +, SchemaEntry("ifcapplication",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcwalltype",&STEP::ObjectHelper<IfcWallType,1>::Construct ) +, SchemaEntry("ifcmove",&STEP::ObjectHelper<IfcMove,3>::Construct ) +, SchemaEntry("ifccircle",&STEP::ObjectHelper<IfcCircle,1>::Construct ) +, SchemaEntry("ifcoffsetcurve2d",&STEP::ObjectHelper<IfcOffsetCurve2D,3>::Construct ) +, SchemaEntry("ifcmateriallayersetusage",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpointoncurve",&STEP::ObjectHelper<IfcPointOnCurve,2>::Construct ) , SchemaEntry("ifcstructuralresultgroup",&STEP::ObjectHelper<IfcStructuralResultGroup,3>::Construct ) -, SchemaEntry("ifcrelspaceboundary",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcorientededge",&STEP::ObjectHelper<IfcOrientedEdge,2>::Construct ) -, SchemaEntry("ifcrelassignstoresource",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcsectionedspine",&STEP::ObjectHelper<IfcSectionedSpine,3>::Construct ) +, SchemaEntry("ifcslab",&STEP::ObjectHelper<IfcSlab,1>::Construct ) +, SchemaEntry("ifcconnectionportgeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcquantityweight",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelassociatesmaterial",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcvertex",&STEP::ObjectHelper<IfcVertex,0>::Construct ) +, SchemaEntry("ifcvertexpoint",&STEP::ObjectHelper<IfcVertexPoint,1>::Construct ) +, SchemaEntry("ifcreferencesvaluedocument",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpersonandorganization",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelflowcontrolelements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcrelassignstoprocess",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructurallinearaction",&STEP::ObjectHelper<IfcStructuralLinearAction,1>::Construct ) +, SchemaEntry("ifcstructurallinearactionvarying",&STEP::ObjectHelper<IfcStructuralLinearActionVarying,2>::Construct ) +, SchemaEntry("ifcbuildingelementproxytype",&STEP::ObjectHelper<IfcBuildingElementProxyType,1>::Construct ) +, SchemaEntry("ifcprojectionelement",&STEP::ObjectHelper<IfcProjectionElement,0>::Construct ) +, SchemaEntry("ifcderivedunit",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcapprovalactorrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcconversionbasedunit",&STEP::ObjectHelper<IfcConversionBasedUnit,2>::Construct ) +, SchemaEntry("ifcmaterial",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcgeometricrepresentationsubcontext",&STEP::ObjectHelper<IfcGeometricRepresentationSubContext,4>::Construct ) +, SchemaEntry("ifcannotationsurfaceoccurrence",&STEP::ObjectHelper<IfcAnnotationSurfaceOccurrence,0>::Construct ) +, SchemaEntry("ifcpredefineddimensionsymbol",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcroundededgefeature",&STEP::ObjectHelper<IfcRoundedEdgeFeature,1>::Construct ) +, SchemaEntry("ifcrelcoversbldgelements",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcelectricdistributionpoint",&STEP::ObjectHelper<IfcElectricDistributionPoint,2>::Construct ) +, SchemaEntry("ifccablecarriersegmenttype",&STEP::ObjectHelper<IfcCableCarrierSegmentType,1>::Construct ) +, SchemaEntry("ifcstructuralloadlinearforce",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcgridaxis",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcirregulartimeseriesvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcwallstandardcase",&STEP::ObjectHelper<IfcWallStandardCase,0>::Construct ) +, SchemaEntry("ifcreloccupiesspaces",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcderivedunitelement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) , SchemaEntry("ifccsgsolid",&STEP::ObjectHelper<IfcCsgSolid,1>::Construct ) -, SchemaEntry("ifcproductsofcombustionproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcbeamtype",&STEP::ObjectHelper<IfcBeamType,1>::Construct ) +, SchemaEntry("ifcannotationfillarea",&STEP::ObjectHelper<IfcAnnotationFillArea,2>::Construct ) , SchemaEntry("ifcrelaxation",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcplanarbox",&STEP::ObjectHelper<IfcPlanarBox,1>::Construct ) -, SchemaEntry("ifcquantitylength",&STEP::ObjectHelper<NotImplemented,0>::Construct ) -, SchemaEntry("ifcmaterialdefinitionrepresentation",&STEP::ObjectHelper<IfcMaterialDefinitionRepresentation,1>::Construct ) -, SchemaEntry("ifcasymmetricishapeprofiledef",&STEP::ObjectHelper<IfcAsymmetricIShapeProfileDef,4>::Construct ) -, SchemaEntry("ifcrepresentationmap",&STEP::ObjectHelper<IfcRepresentationMap,2>::Construct ) +, SchemaEntry("ifcstructuralcurvemembervarying",&STEP::ObjectHelper<IfcStructuralCurveMemberVarying,0>::Construct ) +, SchemaEntry("ifcpointonsurface",&STEP::ObjectHelper<IfcPointOnSurface,3>::Construct ) +, SchemaEntry("ifcpropertydependencyrelationship",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcvertexbasedtexturemap",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcorderaction",&STEP::ObjectHelper<IfcOrderAction,1>::Construct ) +, SchemaEntry("ifclibraryreference",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcedgeloop",&STEP::ObjectHelper<IfcEdgeLoop,1>::Construct ) +, SchemaEntry("ifcannotationfillareaoccurrence",&STEP::ObjectHelper<IfcAnnotationFillAreaOccurrence,2>::Construct ) +, SchemaEntry("ifcrelconnectsstructuralelement",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcworkplan",&STEP::ObjectHelper<IfcWorkPlan,0>::Construct ) +, SchemaEntry("ifcellipse",&STEP::ObjectHelper<IfcEllipse,2>::Construct ) +, SchemaEntry("ifcproductdefinitionshape",&STEP::ObjectHelper<IfcProductDefinitionShape,0>::Construct ) +, SchemaEntry("ifcprojectioncurve",&STEP::ObjectHelper<IfcProjectionCurve,0>::Construct ) +, SchemaEntry("ifcelectricalcircuit",&STEP::ObjectHelper<IfcElectricalCircuit,0>::Construct ) +, SchemaEntry("ifcrationalbeziercurve",&STEP::ObjectHelper<IfcRationalBezierCurve,1>::Construct ) +, SchemaEntry("ifcstructuralpointaction",&STEP::ObjectHelper<IfcStructuralPointAction,0>::Construct ) +, SchemaEntry("ifcservicelifefactor",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcthermalmaterialproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifctexturecoordinategenerator",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpipesegmenttype",&STEP::ObjectHelper<IfcPipeSegmentType,1>::Construct ) +, SchemaEntry("ifctwodirectionrepeatfactor",&STEP::ObjectHelper<IfcTwoDirectionRepeatFactor,1>::Construct ) +, SchemaEntry("ifcshaperepresentation",&STEP::ObjectHelper<IfcShapeRepresentation,0>::Construct ) +, SchemaEntry("ifcpropertyset",&STEP::ObjectHelper<IfcPropertySet,1>::Construct ) +, SchemaEntry("ifcsurfacestylerendering",&STEP::ObjectHelper<IfcSurfaceStyleRendering,8>::Construct ) +, SchemaEntry("ifcdistributionport",&STEP::ObjectHelper<IfcDistributionPort,1>::Construct ) +, SchemaEntry("ifcimagetexture",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcpipefittingtype",&STEP::ObjectHelper<IfcPipeFittingType,1>::Construct ) +, SchemaEntry("ifctransportelement",&STEP::ObjectHelper<IfcTransportElement,3>::Construct ) +, SchemaEntry("ifcannotationtextoccurrence",&STEP::ObjectHelper<IfcAnnotationTextOccurrence,0>::Construct ) +, SchemaEntry("ifcconnectionsurfacegeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcstructuralanalysismodel",&STEP::ObjectHelper<IfcStructuralAnalysisModel,4>::Construct ) +, SchemaEntry("ifcconnectioncurvegeometry",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcconditioncriterion",&STEP::ObjectHelper<IfcConditionCriterion,2>::Construct ) +, SchemaEntry("ifcwaterproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifcmateriallayer",&STEP::ObjectHelper<NotImplemented,0>::Construct ) +, SchemaEntry("ifccostvalue",&STEP::ObjectHelper<NotImplemented,0>::Construct ) }; } @@ -1045,7 +1045,7 @@ void IFC::GetSchema(EXPRESS::ConversionSchema& out) namespace STEP { // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<NotImplemented>(const STEP::DB& /*db*/, const LIST& /*params*/, NotImplemented* /*in*/) +template <> size_t GenericFill<NotImplemented>(const STEP::DB& db, const LIST& params, NotImplemented* in) { return 0; } @@ -1112,110 +1112,130 @@ template <> size_t GenericFill<IfcElementType>(const DB& db, const LIST& params, return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFurnishingElementType>(const DB& db, const LIST& params, IfcFurnishingElementType* in) +template <> size_t GenericFill<IfcDistributionElementType>(const DB& db, const LIST& params, IfcDistributionElementType* in) { size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFurnitureType>(const DB& db, const LIST& params, IfcFurnitureType* in) +template <> size_t GenericFill<IfcDistributionFlowElementType>(const DB& db, const LIST& params, IfcDistributionFlowElementType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFurnishingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcObject>(const DB& db, const LIST& params, IfcObject* in) +template <> size_t GenericFill<IfcFlowControllerType>(const DB& db, const LIST& params, IfcFlowControllerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcObjectDefinition*>(in)); - if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcObject"); } do { // convert the 'ObjectType' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcObject,1>::aux_is_derived[0]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ObjectType, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcObject to be a `IfcLabel`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProduct>(const DB& db, const LIST& params, IfcProduct* in) +template <> size_t GenericFill<IfcElectricTimeControlType>(const DB& db, const LIST& params, IfcElectricTimeControlType* in) { - size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); - if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcProduct"); } do { // convert the 'ObjectPlacement' argument + size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcRepresentation>(const DB& db, const LIST& params, IfcRepresentation* in) +{ + size_t base = 0; + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRepresentation"); } do { // convert the 'ContextOfItems' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProduct,2>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->ContextOfItems, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentation to be a `IfcRepresentationContext`")); } + } while(0); + do { // convert the 'RepresentationIdentifier' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[1]=true; break; } if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ObjectPlacement, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProduct to be a `IfcObjectPlacement`")); } + try { GenericConvert( in->RepresentationIdentifier, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentation to be a `IfcLabel`")); } } while(0); - do { // convert the 'Representation' argument + do { // convert the 'RepresentationType' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProduct,2>::aux_is_derived[1]=true; break; } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[2]=true; break; } if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Representation, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProduct to be a `IfcProductRepresentation`")); } + try { GenericConvert( in->RepresentationType, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRepresentation to be a `IfcLabel`")); } + } while(0); + do { // convert the 'Items' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[3]=true; break; } + try { GenericConvert( in->Items, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRepresentation to be a `SET [1:?] OF IfcRepresentationItem`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGrid>(const DB& db, const LIST& params, IfcGrid* in) +template <> size_t GenericFill<IfcShapeModel>(const DB& db, const LIST& params, IfcShapeModel* in) { - size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcRepresentation*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRepresentationItem>(const DB& /*db*/, const LIST& /*params*/, IfcRepresentationItem* /*in*/) +template <> size_t GenericFill<IfcTopologyRepresentation>(const DB& db, const LIST& params, IfcTopologyRepresentation* in) { - size_t base = 0; + size_t base = GenericFill(db,params,static_cast<IfcShapeModel*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGeometricRepresentationItem>(const DB& db, const LIST& params, IfcGeometricRepresentationItem* in) +template <> size_t GenericFill<IfcRelationship>(const DB& db, const LIST& params, IfcRelationship* in) { - size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in)); - return base; + size_t base = GenericFill(db,params,static_cast<IfcRoot*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRelationship"); } return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOneDirectionRepeatFactor>(const DB& db, const LIST& params, IfcOneDirectionRepeatFactor* in) +template <> size_t GenericFill<IfcRelConnects>(const DB& db, const LIST& params, IfcRelConnects* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcRelationship*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRelConnects"); } return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcFlowFittingType>(const DB& db, const LIST& params, IfcFlowFittingType* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTwoDirectionRepeatFactor>(const DB& db, const LIST& params, IfcTwoDirectionRepeatFactor* in) +template <> size_t GenericFill<IfcCableCarrierFittingType>(const DB& db, const LIST& params, IfcCableCarrierFittingType* in) { - size_t base = GenericFill(db,params,static_cast<IfcOneDirectionRepeatFactor*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElement>(const DB& db, const LIST& params, IfcElement* in) +template <> size_t GenericFill<IfcEnergyConversionDeviceType>(const DB& db, const LIST& params, IfcEnergyConversionDeviceType* in) { - size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); - if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcElement"); } do { // convert the 'Tag' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcElement,1>::aux_is_derived[0]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Tag, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcElement to be a `IfcIdentifier`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElementComponent>(const DB& db, const LIST& params, IfcElementComponent* in) +template <> size_t GenericFill<IfcCoilType>(const DB& db, const LIST& params, IfcCoilType* in) { - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSpatialStructureElementType>(const DB& db, const LIST& params, IfcSpatialStructureElementType* in) +template <> size_t GenericFill<IfcObject>(const DB& db, const LIST& params, IfcObject* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcObjectDefinition*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcObject"); } do { // convert the 'ObjectType' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcObject,1>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ObjectType, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcObject to be a `IfcLabel`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- @@ -1226,187 +1246,263 @@ template <> size_t GenericFill<IfcControl>(const DB& db, const LIST& params, Ifc return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcActionRequest>(const DB& db, const LIST& params, IfcActionRequest* in) +template <> size_t GenericFill<IfcPerformanceHistory>(const DB& db, const LIST& params, IfcPerformanceHistory* in) { size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionElementType>(const DB& db, const LIST& params, IfcDistributionElementType* in) +template <> size_t GenericFill<IfcRepresentationItem>(const DB& db, const LIST& params, IfcRepresentationItem* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = 0; return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionFlowElementType>(const DB& db, const LIST& params, IfcDistributionFlowElementType* in) +template <> size_t GenericFill<IfcGeometricRepresentationItem>(const DB& db, const LIST& params, IfcGeometricRepresentationItem* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionElementType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in)); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEnergyConversionDeviceType>(const DB& db, const LIST& params, IfcEnergyConversionDeviceType* in) +template <> size_t GenericFill<IfcTextLiteral>(const DB& db, const LIST& params, IfcTextLiteral* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCooledBeamType>(const DB& db, const LIST& params, IfcCooledBeamType* in) +template <> size_t GenericFill<IfcTextLiteralWithExtent>(const DB& db, const LIST& params, IfcTextLiteralWithExtent* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcTextLiteral*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCsgPrimitive3D>(const DB& db, const LIST& params, IfcCsgPrimitive3D* in) +template <> size_t GenericFill<IfcProductRepresentation>(const DB& db, const LIST& params, IfcProductRepresentation* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = 0; + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcProductRepresentation"); } do { // convert the 'Name' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Name, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProductRepresentation to be a `IfcLabel`")); } + } while(0); + do { // convert the 'Description' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[1]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Description, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProductRepresentation to be a `IfcText`")); } + } while(0); + do { // convert the 'Representations' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[2]=true; break; } + try { GenericConvert( in->Representations, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcProductRepresentation to be a `LIST [1:?] OF IfcRepresentation`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRectangularPyramid>(const DB& db, const LIST& params, IfcRectangularPyramid* in) +template <> size_t GenericFill<IfcProduct>(const DB& db, const LIST& params, IfcProduct* in) { - size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); + if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcProduct"); } do { // convert the 'ObjectPlacement' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProduct,2>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ObjectPlacement, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProduct to be a `IfcObjectPlacement`")); } + } while(0); + do { // convert the 'Representation' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProduct,2>::aux_is_derived[1]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Representation, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProduct to be a `IfcProductRepresentation`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSurface>(const DB& db, const LIST& params, IfcSurface* in) +template <> size_t GenericFill<IfcElement>(const DB& db, const LIST& params, IfcElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); + if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcElement"); } do { // convert the 'Tag' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcElement,1>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Tag, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcElement to be a `IfcIdentifier`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBoundedSurface>(const DB& db, const LIST& params, IfcBoundedSurface* in) +template <> size_t GenericFill<IfcDistributionElement>(const DB& db, const LIST& params, IfcDistributionElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRectangularTrimmedSurface>(const DB& db, const LIST& params, IfcRectangularTrimmedSurface* in) +template <> size_t GenericFill<IfcDistributionFlowElement>(const DB& db, const LIST& params, IfcDistributionFlowElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcBoundedSurface*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGroup>(const DB& db, const LIST& params, IfcGroup* in) +template <> size_t GenericFill<IfcCurve>(const DB& db, const LIST& params, IfcCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRelationship>(const DB& db, const LIST& params, IfcRelationship* in) +template <> size_t GenericFill<IfcBoundedCurve>(const DB& db, const LIST& params, IfcBoundedCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcRoot*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRelationship"); } return base; + size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); + return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcHalfSpaceSolid>(const DB& db, const LIST& params, IfcHalfSpaceSolid* in) +template <> size_t GenericFill<IfcCompositeCurve>(const DB& db, const LIST& params, IfcCompositeCurve* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCompositeCurve"); } do { // convert the 'Segments' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCompositeCurve,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Segments, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurve to be a `LIST [1:?] OF IfcCompositeCurveSegment`")); } + } while(0); + do { // convert the 'SelfIntersect' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCompositeCurve,2>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->SelfIntersect, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurve to be a `LOGICAL`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<Ifc2DCompositeCurve>(const DB& db, const LIST& params, Ifc2DCompositeCurve* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcCompositeCurve*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcCartesianTransformationOperator>(const DB& db, const LIST& params, IfcCartesianTransformationOperator* in) { size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcHalfSpaceSolid"); } do { // convert the 'BaseSurface' argument + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCartesianTransformationOperator"); } do { // convert the 'Axis1' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcHalfSpaceSolid,2>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->BaseSurface, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcHalfSpaceSolid to be a `IfcSurface`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Axis1, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianTransformationOperator to be a `IfcDirection`")); } } while(0); - do { // convert the 'AgreementFlag' argument + do { // convert the 'Axis2' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcHalfSpaceSolid,2>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->AgreementFlag, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcHalfSpaceSolid to be a `BOOLEAN`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[1]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Axis2, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCartesianTransformationOperator to be a `IfcDirection`")); } + } while(0); + do { // convert the 'LocalOrigin' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[2]=true; break; } + try { GenericConvert( in->LocalOrigin, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCartesianTransformationOperator to be a `IfcCartesianPoint`")); } + } while(0); + do { // convert the 'Scale' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[3]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Scale, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCartesianTransformationOperator to be a `REAL`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPolygonalBoundedHalfSpace>(const DB& db, const LIST& params, IfcPolygonalBoundedHalfSpace* in) +template <> size_t GenericFill<IfcCartesianTransformationOperator3D>(const DB& db, const LIST& params, IfcCartesianTransformationOperator3D* in) { - size_t base = GenericFill(db,params,static_cast<IfcHalfSpaceSolid*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPolygonalBoundedHalfSpace"); } do { // convert the 'Position' argument + size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCartesianTransformationOperator3D"); } do { // convert the 'Axis3' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Position, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPolygonalBoundedHalfSpace to be a `IfcAxis2Placement3D`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator3D,1>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Axis3, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCartesianTransformationOperator3D to be a `IfcDirection`")); } } while(0); - do { // convert the 'PolygonalBoundary' argument + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcProperty>(const DB& db, const LIST& params, IfcProperty* in) +{ + size_t base = 0; + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProperty"); } do { // convert the 'Name' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->PolygonalBoundary, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPolygonalBoundedHalfSpace to be a `IfcBoundedCurve`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProperty,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Name, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProperty to be a `IfcIdentifier`")); } + } while(0); + do { // convert the 'Description' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProperty,2>::aux_is_derived[1]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Description, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProperty to be a `IfcText`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAirToAirHeatRecoveryType>(const DB& db, const LIST& params, IfcAirToAirHeatRecoveryType* in) +template <> size_t GenericFill<IfcSimpleProperty>(const DB& db, const LIST& params, IfcSimpleProperty* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProperty*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcSimpleProperty"); } return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcPropertyEnumeratedValue>(const DB& db, const LIST& params, IfcPropertyEnumeratedValue* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowFittingType>(const DB& db, const LIST& params, IfcFlowFittingType* in) +template <> size_t GenericFill<IfcBuildingElementType>(const DB& db, const LIST& params, IfcBuildingElementType* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPipeFittingType>(const DB& db, const LIST& params, IfcPipeFittingType* in) +template <> size_t GenericFill<IfcStairFlightType>(const DB& db, const LIST& params, IfcStairFlightType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRepresentation>(const DB& db, const LIST& params, IfcRepresentation* in) +template <> size_t GenericFill<IfcSurface>(const DB& db, const LIST& params, IfcSurface* in) { - size_t base = 0; - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRepresentation"); } do { // convert the 'ContextOfItems' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->ContextOfItems, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentation to be a `IfcRepresentationContext`")); } - } while(0); - do { // convert the 'RepresentationIdentifier' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[1]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->RepresentationIdentifier, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentation to be a `IfcLabel`")); } - } while(0); - do { // convert the 'RepresentationType' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[2]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->RepresentationType, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRepresentation to be a `IfcLabel`")); } - } while(0); - do { // convert the 'Items' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentation,4>::aux_is_derived[3]=true; break; } - try { GenericConvert( in->Items, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRepresentation to be a `SET [1:?] OF IfcRepresentationItem`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStyleModel>(const DB& db, const LIST& params, IfcStyleModel* in) +template <> size_t GenericFill<IfcElementarySurface>(const DB& db, const LIST& params, IfcElementarySurface* in) { - size_t base = GenericFill(db,params,static_cast<IfcRepresentation*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcElementarySurface"); } do { // convert the 'Position' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcElementarySurface,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Position, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcElementarySurface to be a `IfcAxis2Placement3D`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStyledRepresentation>(const DB& db, const LIST& params, IfcStyledRepresentation* in) +template <> size_t GenericFill<IfcPlane>(const DB& db, const LIST& params, IfcPlane* in) { - size_t base = GenericFill(db,params,static_cast<IfcStyleModel*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members - return base; + size_t base = GenericFill(db,params,static_cast<IfcElementarySurface*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPlane"); } return base; } // ----------------------------------------------------------------------------------------------------------- template <> size_t GenericFill<IfcBooleanResult>(const DB& db, const LIST& params, IfcBooleanResult* in) @@ -1433,1664 +1529,1711 @@ template <> size_t GenericFill<IfcBooleanResult>(const DB& db, const LIST& param return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFeatureElement>(const DB& db, const LIST& params, IfcFeatureElement* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); - if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcFeatureElement"); } return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFeatureElementSubtraction>(const DB& db, const LIST& params, IfcFeatureElementSubtraction* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcFeatureElement*>(in)); - if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcFeatureElementSubtraction"); } return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOpeningElement>(const DB& db, const LIST& params, IfcOpeningElement* in) +template <> size_t GenericFill<IfcBooleanClippingResult>(const DB& db, const LIST& params, IfcBooleanClippingResult* in) { - size_t base = GenericFill(db,params,static_cast<IfcFeatureElementSubtraction*>(in)); - if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcOpeningElement"); } return base; + size_t base = GenericFill(db,params,static_cast<IfcBooleanResult*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcBooleanClippingResult"); } return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcConditionCriterion>(const DB& db, const LIST& params, IfcConditionCriterion* in) +template <> size_t GenericFill<IfcSolidModel>(const DB& db, const LIST& params, IfcSolidModel* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowTerminalType>(const DB& db, const LIST& params, IfcFlowTerminalType* in) +template <> size_t GenericFill<IfcManifoldSolidBrep>(const DB& db, const LIST& params, IfcManifoldSolidBrep* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcManifoldSolidBrep"); } do { // convert the 'Outer' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcManifoldSolidBrep,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Outer, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcManifoldSolidBrep to be a `IfcClosedShell`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowControllerType>(const DB& db, const LIST& params, IfcFlowControllerType* in) +template <> size_t GenericFill<IfcFlowTerminalType>(const DB& db, const LIST& params, IfcFlowTerminalType* in) { size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSwitchingDeviceType>(const DB& db, const LIST& params, IfcSwitchingDeviceType* in) +template <> size_t GenericFill<IfcStackTerminalType>(const DB& db, const LIST& params, IfcStackTerminalType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSystem>(const DB& db, const LIST& params, IfcSystem* in) +template <> size_t GenericFill<IfcStructuralItem>(const DB& db, const LIST& params, IfcStructuralItem* in) { - size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricalCircuit>(const DB& db, const LIST& params, IfcElectricalCircuit* in) +template <> size_t GenericFill<IfcStructuralConnection>(const DB& db, const LIST& params, IfcStructuralConnection* in) { - size_t base = GenericFill(db,params,static_cast<IfcSystem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcUnitaryEquipmentType>(const DB& db, const LIST& params, IfcUnitaryEquipmentType* in) +template <> size_t GenericFill<IfcStructuralCurveConnection>(const DB& db, const LIST& params, IfcStructuralCurveConnection* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPort>(const DB& db, const LIST& params, IfcPort* in) +template <> size_t GenericFill<IfcJunctionBoxType>(const DB& db, const LIST& params, IfcJunctionBoxType* in) { - size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPlacement>(const DB& db, const LIST& params, IfcPlacement* in) +template <> size_t GenericFill<IfcPropertyDefinition>(const DB& db, const LIST& params, IfcPropertyDefinition* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPlacement"); } do { // convert the 'Location' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcPlacement,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Location, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPlacement to be a `IfcCartesianPoint`")); } - } while(0); - return base; + size_t base = GenericFill(db,params,static_cast<IfcRoot*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertyDefinition"); } return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProfileDef>(const DB& db, const LIST& params, IfcProfileDef* in) +template <> size_t GenericFill<IfcPropertySetDefinition>(const DB& db, const LIST& params, IfcPropertySetDefinition* in) { - size_t base = 0; - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProfileDef"); } do { // convert the 'ProfileType' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProfileDef,2>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->ProfileType, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProfileDef to be a `IfcProfileTypeEnum`")); } - } while(0); - do { // convert the 'ProfileName' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProfileDef,2>::aux_is_derived[1]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ProfileName, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProfileDef to be a `IfcLabel`")); } - } while(0); - return base; + size_t base = GenericFill(db,params,static_cast<IfcPropertyDefinition*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertySetDefinition"); } return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcArbitraryClosedProfileDef>(const DB& db, const LIST& params, IfcArbitraryClosedProfileDef* in) +template <> size_t GenericFill<IfcProcess>(const DB& db, const LIST& params, IfcProcess* in) { - size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryClosedProfileDef"); } do { // convert the 'OuterCurve' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcArbitraryClosedProfileDef,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->OuterCurve, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryClosedProfileDef to be a `IfcCurve`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCurve>(const DB& db, const LIST& params, IfcCurve* in) +template <> size_t GenericFill<IfcTask>(const DB& db, const LIST& params, IfcTask* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProcess*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcConic>(const DB& db, const LIST& params, IfcConic* in) +template <> size_t GenericFill<IfcRelFillsElement>(const DB& db, const LIST& params, IfcRelFillsElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConic"); } do { // convert the 'Position' argument + size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in)); + if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelFillsElement"); } do { // convert the 'RelatingOpeningElement' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcConic,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Position, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConic to be a `IfcAxis2Placement`")); } + try { GenericConvert( in->RelatingOpeningElement, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelFillsElement to be a `IfcOpeningElement`")); } } while(0); - return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCircle>(const DB& db, const LIST& params, IfcCircle* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcConic*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCircle"); } do { // convert the 'Radius' argument + do { // convert the 'RelatedBuildingElement' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Radius, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCircle to be a `IfcPositiveLengthMeasure`")); } + try { GenericConvert( in->RelatedBuildingElement, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelFillsElement to be a `IfcElement`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElementarySurface>(const DB& db, const LIST& params, IfcElementarySurface* in) +template <> size_t GenericFill<IfcProcedure>(const DB& db, const LIST& params, IfcProcedure* in) { - size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcElementarySurface"); } do { // convert the 'Position' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcElementarySurface,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Position, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcElementarySurface to be a `IfcAxis2Placement3D`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcProcess*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPlane>(const DB& db, const LIST& params, IfcPlane* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcElementarySurface*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPlane"); } return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCostSchedule>(const DB& db, const LIST& params, IfcCostSchedule* in) +template <> size_t GenericFill<IfcProxy>(const DB& db, const LIST& params, IfcProxy* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRightCircularCone>(const DB& db, const LIST& params, IfcRightCircularCone* in) +template <> size_t GenericFill<IfcResource>(const DB& db, const LIST& params, IfcResource* in) { - size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElementAssembly>(const DB& db, const LIST& params, IfcElementAssembly* in) +template <> size_t GenericFill<IfcConstructionResource>(const DB& db, const LIST& params, IfcConstructionResource* in) { - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcResource*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBuildingElement>(const DB& db, const LIST& params, IfcBuildingElement* in) +template <> size_t GenericFill<IfcSubContractResource>(const DB& db, const LIST& params, IfcSubContractResource* in) { - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); - if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcBuildingElement"); } return base; + size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members + return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMember>(const DB& db, const LIST& params, IfcMember* in) +template <> size_t GenericFill<IfcRelContainedInSpatialStructure>(const DB& db, const LIST& params, IfcRelContainedInSpatialStructure* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in)); + if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelContainedInSpatialStructure"); } do { // convert the 'RelatedElements' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->RelatedElements, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelContainedInSpatialStructure to be a `SET [1:?] OF IfcProduct`")); } + } while(0); + do { // convert the 'RelatingStructure' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->RelatingStructure, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelContainedInSpatialStructure to be a `IfcSpatialStructureElement`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBuildingElementProxy>(const DB& db, const LIST& params, IfcBuildingElementProxy* in) +template <> size_t GenericFill<IfcTopologicalRepresentationItem>(const DB& db, const LIST& params, IfcTopologicalRepresentationItem* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in)); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralActivity>(const DB& db, const LIST& params, IfcStructuralActivity* in) +template <> size_t GenericFill<IfcEdge>(const DB& db, const LIST& params, IfcEdge* in) { - size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralAction>(const DB& db, const LIST& params, IfcStructuralAction* in) +template <> size_t GenericFill<IfcEdgeCurve>(const DB& db, const LIST& params, IfcEdgeCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralActivity*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralPlanarAction>(const DB& db, const LIST& params, IfcStructuralPlanarAction* in) +template <> size_t GenericFill<IfcPlateType>(const DB& db, const LIST& params, IfcPlateType* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTopologicalRepresentationItem>(const DB& db, const LIST& params, IfcTopologicalRepresentationItem* in) +template <> size_t GenericFill<IfcObjectPlacement>(const DB& db, const LIST& params, IfcObjectPlacement* in) { - size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in)); + size_t base = 0; return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcConnectedFaceSet>(const DB& db, const LIST& params, IfcConnectedFaceSet* in) +template <> size_t GenericFill<IfcGridPlacement>(const DB& db, const LIST& params, IfcGridPlacement* in) { - size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConnectedFaceSet"); } do { // convert the 'CfsFaces' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcConnectedFaceSet,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->CfsFaces, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConnectedFaceSet to be a `SET [1:?] OF IfcFace`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcObjectPlacement*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSweptSurface>(const DB& db, const LIST& params, IfcSweptSurface* in) +template <> size_t GenericFill<IfcFireSuppressionTerminalType>(const DB& db, const LIST& params, IfcFireSuppressionTerminalType* in) { - size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSurfaceOfLinearExtrusion>(const DB& db, const LIST& params, IfcSurfaceOfLinearExtrusion* in) +template <> size_t GenericFill<IfcFlowStorageDevice>(const DB& db, const LIST& params, IfcFlowStorageDevice* in) { - size_t base = GenericFill(db,params,static_cast<IfcSweptSurface*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcArbitraryProfileDefWithVoids>(const DB& db, const LIST& params, IfcArbitraryProfileDefWithVoids* in) +template <> size_t GenericFill<IfcSweptSurface>(const DB& db, const LIST& params, IfcSweptSurface* in) { - size_t base = GenericFill(db,params,static_cast<IfcArbitraryClosedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProcess>(const DB& db, const LIST& params, IfcProcess* in) +template <> size_t GenericFill<IfcSurfaceOfRevolution>(const DB& db, const LIST& params, IfcSurfaceOfRevolution* in) { - size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSweptSurface*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProcedure>(const DB& db, const LIST& params, IfcProcedure* in) +template <> size_t GenericFill<IfcOrientedEdge>(const DB& db, const LIST& params, IfcOrientedEdge* in) { - size_t base = GenericFill(db,params,static_cast<IfcProcess*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcVector>(const DB& db, const LIST& params, IfcVector* in) +template <> size_t GenericFill<IfcDirection>(const DB& db, const LIST& params, IfcDirection* in) { size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcVector"); } do { // convert the 'Orientation' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Orientation, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcVector to be a `IfcDirection`")); } - } while(0); - do { // convert the 'Magnitude' argument + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcDirection"); } do { // convert the 'DirectionRatios' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Magnitude, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcVector to be a `IfcLengthMeasure`")); } + try { GenericConvert( in->DirectionRatios, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcDirection to be a `LIST [2:3] OF REAL`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFaceBound>(const DB& db, const LIST& params, IfcFaceBound* in) +template <> size_t GenericFill<IfcProfileDef>(const DB& db, const LIST& params, IfcProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcFaceBound"); } do { // convert the 'Bound' argument + size_t base = 0; + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProfileDef"); } do { // convert the 'ProfileType' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFaceBound,2>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Bound, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBound to be a `IfcLoop`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProfileDef,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->ProfileType, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProfileDef to be a `IfcProfileTypeEnum`")); } } while(0); - do { // convert the 'Orientation' argument + do { // convert the 'ProfileName' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFaceBound,2>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->Orientation, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcFaceBound to be a `BOOLEAN`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProfileDef,2>::aux_is_derived[1]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ProfileName, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProfileDef to be a `IfcLabel`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFaceOuterBound>(const DB& db, const LIST& params, IfcFaceOuterBound* in) +template <> size_t GenericFill<IfcParameterizedProfileDef>(const DB& db, const LIST& params, IfcParameterizedProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcFaceBound*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcFaceOuterBound"); } return base; + size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcParameterizedProfileDef"); } do { // convert the 'Position' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcParameterizedProfileDef,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Position, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcParameterizedProfileDef to be a `IfcAxis2Placement2D`")); } + } while(0); + return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFeatureElementAddition>(const DB& db, const LIST& params, IfcFeatureElementAddition* in) +template <> size_t GenericFill<IfcCShapeProfileDef>(const DB& db, const LIST& params, IfcCShapeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcFeatureElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcNamedUnit>(const DB& db, const LIST& params, IfcNamedUnit* in) +template <> size_t GenericFill<IfcFeatureElement>(const DB& db, const LIST& params, IfcFeatureElement* in) { - size_t base = 0; - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcNamedUnit"); } do { // convert the 'Dimensions' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcNamedUnit,2>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Dimensions, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcNamedUnit to be a `IfcDimensionalExponents`")); } - } while(0); - do { // convert the 'UnitType' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcNamedUnit,2>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->UnitType, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcNamedUnit to be a `IfcUnitEnum`")); } - } while(0); - return base; + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); + if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcFeatureElement"); } return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcConversionBasedUnit>(const DB& db, const LIST& params, IfcConversionBasedUnit* in) +template <> size_t GenericFill<IfcFeatureElementSubtraction>(const DB& db, const LIST& params, IfcFeatureElementSubtraction* in) { - size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcConversionBasedUnit"); } do { // convert the 'Name' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Name, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcConversionBasedUnit to be a `IfcLabel`")); } - } while(0); - do { // convert the 'ConversionFactor' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->ConversionFactor, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcConversionBasedUnit to be a `IfcMeasureWithUnit`")); } - } while(0); - return base; + size_t base = GenericFill(db,params,static_cast<IfcFeatureElement*>(in)); + if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcFeatureElementSubtraction"); } return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcHeatExchangerType>(const DB& db, const LIST& params, IfcHeatExchangerType* in) +template <> size_t GenericFill<IfcEdgeFeature>(const DB& db, const LIST& params, IfcEdgeFeature* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFeatureElementSubtraction*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPresentationStyleAssignment>(const DB& db, const LIST& params, IfcPresentationStyleAssignment* in) +template <> size_t GenericFill<IfcChamferEdgeFeature>(const DB& db, const LIST& params, IfcChamferEdgeFeature* in) { - size_t base = 0; - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyleAssignment"); } do { // convert the 'Styles' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Styles, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyleAssignment to be a `SET [1:?] OF IfcPresentationStyleSelect`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcEdgeFeature*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowTreatmentDeviceType>(const DB& db, const LIST& params, IfcFlowTreatmentDeviceType* in) +template <> size_t GenericFill<IfcBuildingElement>(const DB& db, const LIST& params, IfcBuildingElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); + if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcBuildingElement"); } return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcColumn>(const DB& db, const LIST& params, IfcColumn* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFilterType>(const DB& db, const LIST& params, IfcFilterType* in) +template <> size_t GenericFill<IfcPropertyReferenceValue>(const DB& db, const LIST& params, IfcPropertyReferenceValue* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTreatmentDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcResource>(const DB& db, const LIST& params, IfcResource* in) +template <> size_t GenericFill<IfcElectricMotorType>(const DB& db, const LIST& params, IfcElectricMotorType* in) { - size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEvaporativeCoolerType>(const DB& db, const LIST& params, IfcEvaporativeCoolerType* in) +template <> size_t GenericFill<IfcSpatialStructureElementType>(const DB& db, const LIST& params, IfcSpatialStructureElementType* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOffsetCurve2D>(const DB& db, const LIST& params, IfcOffsetCurve2D* in) +template <> size_t GenericFill<IfcSpaceType>(const DB& db, const LIST& params, IfcSpaceType* in) { - size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEdge>(const DB& db, const LIST& params, IfcEdge* in) +template <> size_t GenericFill<IfcColumnType>(const DB& db, const LIST& params, IfcColumnType* in) { - size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSubedge>(const DB& db, const LIST& params, IfcSubedge* in) +template <> size_t GenericFill<IfcCraneRailAShapeProfileDef>(const DB& db, const LIST& params, IfcCraneRailAShapeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProxy>(const DB& db, const LIST& params, IfcProxy* in) +template <> size_t GenericFill<IfcCondenserType>(const DB& db, const LIST& params, IfcCondenserType* in) { - size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLine>(const DB& db, const LIST& params, IfcLine* in) +template <> size_t GenericFill<IfcCircleProfileDef>(const DB& db, const LIST& params, IfcCircleProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLine"); } do { // convert the 'Pnt' argument + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCircleProfileDef"); } do { // convert the 'Radius' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Pnt, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLine to be a `IfcCartesianPoint`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCircleProfileDef,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Radius, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCircleProfileDef to be a `IfcPositiveLengthMeasure`")); } } while(0); - do { // convert the 'Dir' argument + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcCircleHollowProfileDef>(const DB& db, const LIST& params, IfcCircleHollowProfileDef* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcCircleProfileDef*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCircleHollowProfileDef"); } do { // convert the 'WallThickness' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Dir, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLine to be a `IfcVector`")); } + try { GenericConvert( in->WallThickness, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCircleHollowProfileDef to be a `IfcPositiveLengthMeasure`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcColumn>(const DB& db, const LIST& params, IfcColumn* in) +template <> size_t GenericFill<IfcPlacement>(const DB& db, const LIST& params, IfcPlacement* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPlacement"); } do { // convert the 'Location' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcPlacement,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Location, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPlacement to be a `IfcCartesianPoint`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcObjectPlacement>(const DB& /*db*/, const LIST& /*params*/, IfcObjectPlacement* /*in*/) +template <> size_t GenericFill<IfcAxis2Placement3D>(const DB& db, const LIST& params, IfcAxis2Placement3D* in) { - size_t base = 0; + size_t base = GenericFill(db,params,static_cast<IfcPlacement*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcAxis2Placement3D"); } do { // convert the 'Axis' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Axis, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement3D to be a `IfcDirection`")); } + } while(0); + do { // convert the 'RefDirection' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->RefDirection, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcAxis2Placement3D to be a `IfcDirection`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGridPlacement>(const DB& db, const LIST& params, IfcGridPlacement* in) +template <> size_t GenericFill<IfcPresentationStyle>(const DB& db, const LIST& params, IfcPresentationStyle* in) { - size_t base = GenericFill(db,params,static_cast<IfcObjectPlacement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = 0; + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyle"); } do { // convert the 'Name' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcPresentationStyle,1>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Name, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyle to be a `IfcLabel`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionControlElementType>(const DB& db, const LIST& params, IfcDistributionControlElementType* in) +template <> size_t GenericFill<IfcEquipmentElement>(const DB& db, const LIST& params, IfcEquipmentElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRelConnects>(const DB& db, const LIST& params, IfcRelConnects* in) +template <> size_t GenericFill<IfcCompositeCurveSegment>(const DB& db, const LIST& params, IfcCompositeCurveSegment* in) { - size_t base = GenericFill(db,params,static_cast<IfcRelationship*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRelConnects"); } return base; + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcCompositeCurveSegment"); } do { // convert the 'Transition' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Transition, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurveSegment to be a `IfcTransitionCode`")); } + } while(0); + do { // convert the 'SameSense' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->SameSense, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurveSegment to be a `BOOLEAN`")); } + } while(0); + do { // convert the 'ParentCurve' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->ParentCurve, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCompositeCurveSegment to be a `IfcCurve`")); } + } while(0); + return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotation>(const DB& db, const LIST& params, IfcAnnotation* in) +template <> size_t GenericFill<IfcRectangleProfileDef>(const DB& db, const LIST& params, IfcRectangleProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); - if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcAnnotation"); } return base; + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRectangleProfileDef"); } do { // convert the 'XDim' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRectangleProfileDef,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->XDim, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'YDim' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRectangleProfileDef,2>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->YDim, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); } + } while(0); + return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPlate>(const DB& db, const LIST& params, IfcPlate* in) +template <> size_t GenericFill<IfcBuildingElementProxy>(const DB& db, const LIST& params, IfcBuildingElementProxy* in) { size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSolidModel>(const DB& db, const LIST& params, IfcSolidModel* in) +template <> size_t GenericFill<IfcDistributionControlElementType>(const DB& db, const LIST& params, IfcDistributionControlElementType* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionElementType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcManifoldSolidBrep>(const DB& db, const LIST& params, IfcManifoldSolidBrep* in) +template <> size_t GenericFill<IfcFlowInstrumentType>(const DB& db, const LIST& params, IfcFlowInstrumentType* in) { - size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcManifoldSolidBrep"); } do { // convert the 'Outer' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcManifoldSolidBrep,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Outer, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcManifoldSolidBrep to be a `IfcClosedShell`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowStorageDeviceType>(const DB& db, const LIST& params, IfcFlowStorageDeviceType* in) +template <> size_t GenericFill<IfcDraughtingCallout>(const DB& db, const LIST& params, IfcDraughtingCallout* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralItem>(const DB& db, const LIST& params, IfcStructuralItem* in) +template <> size_t GenericFill<IfcDimensionCurveDirectedCallout>(const DB& db, const LIST& params, IfcDimensionCurveDirectedCallout* in) { - size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDraughtingCallout*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralMember>(const DB& db, const LIST& params, IfcStructuralMember* in) +template <> size_t GenericFill<IfcLinearDimension>(const DB& db, const LIST& params, IfcLinearDimension* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralCurveMember>(const DB& db, const LIST& params, IfcStructuralCurveMember* in) +template <> size_t GenericFill<IfcElementAssembly>(const DB& db, const LIST& params, IfcElementAssembly* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralMember*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralConnection>(const DB& db, const LIST& params, IfcStructuralConnection* in) +template <> size_t GenericFill<IfcCsgPrimitive3D>(const DB& db, const LIST& params, IfcCsgPrimitive3D* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralSurfaceConnection>(const DB& db, const LIST& params, IfcStructuralSurfaceConnection* in) +template <> size_t GenericFill<IfcRightCircularCone>(const DB& db, const LIST& params, IfcRightCircularCone* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCoilType>(const DB& db, const LIST& params, IfcCoilType* in) +template <> size_t GenericFill<IfcProjectOrder>(const DB& db, const LIST& params, IfcProjectOrder* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDuctFittingType>(const DB& db, const LIST& params, IfcDuctFittingType* in) +template <> size_t GenericFill<IfcLShapeProfileDef>(const DB& db, const LIST& params, IfcLShapeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStyledItem>(const DB& db, const LIST& params, IfcStyledItem* in) +template <> size_t GenericFill<IfcAngularDimension>(const DB& db, const LIST& params, IfcAngularDimension* in) { - size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcStyledItem"); } do { // convert the 'Item' argument + size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcLocalPlacement>(const DB& db, const LIST& params, IfcLocalPlacement* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcObjectPlacement*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLocalPlacement"); } do { // convert the 'PlacementRelTo' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[0]=true; break; } if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Item, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcStyledItem to be a `IfcRepresentationItem`")); } - } while(0); - do { // convert the 'Styles' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->Styles, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcStyledItem to be a `SET [1:?] OF IfcPresentationStyleAssignment`")); } + try { GenericConvert( in->PlacementRelTo, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLocalPlacement to be a `IfcObjectPlacement`")); } } while(0); - do { // convert the 'Name' argument + do { // convert the 'RelativePlacement' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[2]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Name, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcStyledItem to be a `IfcLabel`")); } + try { GenericConvert( in->RelativePlacement, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLocalPlacement to be a `IfcAxis2Placement`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotationOccurrence>(const DB& db, const LIST& params, IfcAnnotationOccurrence* in) +template <> size_t GenericFill<IfcSweptAreaSolid>(const DB& db, const LIST& params, IfcSweptAreaSolid* in) { - size_t base = GenericFill(db,params,static_cast<IfcStyledItem*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcSweptAreaSolid"); } do { // convert the 'SweptArea' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSweptAreaSolid,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->SweptArea, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptAreaSolid to be a `IfcProfileDef`")); } + } while(0); + do { // convert the 'Position' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSweptAreaSolid,2>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->Position, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptAreaSolid to be a `IfcAxis2Placement3D`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotationCurveOccurrence>(const DB& db, const LIST& params, IfcAnnotationCurveOccurrence* in) +template <> size_t GenericFill<IfcRevolvedAreaSolid>(const DB& db, const LIST& params, IfcRevolvedAreaSolid* in) { - size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRevolvedAreaSolid"); } do { // convert the 'Axis' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Axis, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRevolvedAreaSolid to be a `IfcAxis1Placement`")); } + } while(0); + do { // convert the 'Angle' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Angle, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRevolvedAreaSolid to be a `IfcPlaneAngleMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDimensionCurve>(const DB& db, const LIST& params, IfcDimensionCurve* in) +template <> size_t GenericFill<IfcStructuralSurfaceConnection>(const DB& db, const LIST& params, IfcStructuralSurfaceConnection* in) { - size_t base = GenericFill(db,params,static_cast<IfcAnnotationCurveOccurrence*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBoundedCurve>(const DB& db, const LIST& params, IfcBoundedCurve* in) +template <> size_t GenericFill<IfcRadiusDimension>(const DB& db, const LIST& params, IfcRadiusDimension* in) { - size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAxis1Placement>(const DB& db, const LIST& params, IfcAxis1Placement* in) +template <> size_t GenericFill<IfcSweptDiskSolid>(const DB& db, const LIST& params, IfcSweptDiskSolid* in) { - size_t base = GenericFill(db,params,static_cast<IfcPlacement*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis1Placement"); } do { // convert the 'Axis' argument + size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcSweptDiskSolid"); } do { // convert the 'Directrix' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Directrix, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptDiskSolid to be a `IfcCurve`")); } + } while(0); + do { // convert the 'Radius' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Radius, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptDiskSolid to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'InnerRadius' argument boost::shared_ptr<const DataType> arg = params[base++]; if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Axis, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis1Placement to be a `IfcDirection`")); } + try { GenericConvert( in->InnerRadius, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSweptDiskSolid to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'StartParam' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->StartParam, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSweptDiskSolid to be a `IfcParameterValue`")); } + } while(0); + do { // convert the 'EndParam' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->EndParam, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSweptDiskSolid to be a `IfcParameterValue`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralPointAction>(const DB& db, const LIST& params, IfcStructuralPointAction* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members - return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSpatialStructureElement>(const DB& db, const LIST& params, IfcSpatialStructureElement* in) +template <> size_t GenericFill<IfcHalfSpaceSolid>(const DB& db, const LIST& params, IfcHalfSpaceSolid* in) { - size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); - if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcSpatialStructureElement"); } do { // convert the 'LongName' argument + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcHalfSpaceSolid"); } do { // convert the 'BaseSurface' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSpatialStructureElement,2>::aux_is_derived[0]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->LongName, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSpatialStructureElement to be a `IfcLabel`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcHalfSpaceSolid,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->BaseSurface, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcHalfSpaceSolid to be a `IfcSurface`")); } } while(0); - do { // convert the 'CompositionType' argument + do { // convert the 'AgreementFlag' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSpatialStructureElement,2>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->CompositionType, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSpatialStructureElement to be a `IfcElementCompositionEnum`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcHalfSpaceSolid,2>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->AgreementFlag, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcHalfSpaceSolid to be a `BOOLEAN`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSpace>(const DB& db, const LIST& params, IfcSpace* in) +template <> size_t GenericFill<IfcPolygonalBoundedHalfSpace>(const DB& db, const LIST& params, IfcPolygonalBoundedHalfSpace* in) { - size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in)); - if (params.GetSize() < 11) { throw STEP::TypeError("expected 11 arguments to IfcSpace"); } do { // convert the 'InteriorOrExteriorSpace' argument + size_t base = GenericFill(db,params,static_cast<IfcHalfSpaceSolid*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPolygonalBoundedHalfSpace"); } do { // convert the 'Position' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->InteriorOrExteriorSpace, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSpace to be a `IfcInternalOrExternalEnum`")); } + try { GenericConvert( in->Position, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPolygonalBoundedHalfSpace to be a `IfcAxis2Placement3D`")); } } while(0); - do { // convert the 'ElevationWithFlooring' argument + do { // convert the 'PolygonalBoundary' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ElevationWithFlooring, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSpace to be a `IfcLengthMeasure`")); } + try { GenericConvert( in->PolygonalBoundary, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPolygonalBoundedHalfSpace to be a `IfcBoundedCurve`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcContextDependentUnit>(const DB& db, const LIST& params, IfcContextDependentUnit* in) +template <> size_t GenericFill<IfcTimeSeriesSchedule>(const DB& db, const LIST& params, IfcTimeSeriesSchedule* in) { - size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCoolingTowerType>(const DB& db, const LIST& params, IfcCoolingTowerType* in) +template <> size_t GenericFill<IfcCooledBeamType>(const DB& db, const LIST& params, IfcCooledBeamType* in) { size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFacetedBrepWithVoids>(const DB& db, const LIST& params, IfcFacetedBrepWithVoids* in) +template <> size_t GenericFill<IfcProject>(const DB& db, const LIST& params, IfcProject* in) { - size_t base = GenericFill(db,params,static_cast<IfcManifoldSolidBrep*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); + if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcProject"); } do { // convert the 'LongName' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->LongName, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProject to be a `IfcLabel`")); } + } while(0); + do { // convert the 'Phase' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Phase, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProject to be a `IfcLabel`")); } + } while(0); + do { // convert the 'RepresentationContexts' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->RepresentationContexts, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcProject to be a `SET [1:?] OF IfcRepresentationContext`")); } + } while(0); + do { // convert the 'UnitsInContext' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->UnitsInContext, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcProject to be a `IfcUnitAssignment`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcValveType>(const DB& db, const LIST& params, IfcValveType* in) +template <> size_t GenericFill<IfcEvaporatorType>(const DB& db, const LIST& params, IfcEvaporatorType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSystemFurnitureElementType>(const DB& db, const LIST& params, IfcSystemFurnitureElementType* in) +template <> size_t GenericFill<IfcLaborResource>(const DB& db, const LIST& params, IfcLaborResource* in) { - size_t base = GenericFill(db,params,static_cast<IfcFurnishingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDiscreteAccessory>(const DB& db, const LIST& params, IfcDiscreteAccessory* in) +template <> size_t GenericFill<IfcPropertyBoundedValue>(const DB& db, const LIST& params, IfcPropertyBoundedValue* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementComponent*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBuildingElementType>(const DB& db, const LIST& params, IfcBuildingElementType* in) +template <> size_t GenericFill<IfcRampFlightType>(const DB& db, const LIST& params, IfcRampFlightType* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRailingType>(const DB& db, const LIST& params, IfcRailingType* in) +template <> size_t GenericFill<IfcMember>(const DB& db, const LIST& params, IfcMember* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGasTerminalType>(const DB& db, const LIST& params, IfcGasTerminalType* in) +template <> size_t GenericFill<IfcTubeBundleType>(const DB& db, const LIST& params, IfcTubeBundleType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSpaceProgram>(const DB& db, const LIST& params, IfcSpaceProgram* in) +template <> size_t GenericFill<IfcValveType>(const DB& db, const LIST& params, IfcValveType* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCovering>(const DB& db, const LIST& params, IfcCovering* in) +template <> size_t GenericFill<IfcTrimmedCurve>(const DB& db, const LIST& params, IfcTrimmedCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcTrimmedCurve"); } do { // convert the 'BasisCurve' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->BasisCurve, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcTrimmedCurve to be a `IfcCurve`")); } + } while(0); + do { // convert the 'Trim1' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Trim1, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); } + } while(0); + do { // convert the 'Trim2' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Trim2, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); } + } while(0); + do { // convert the 'SenseAgreement' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->SenseAgreement, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcTrimmedCurve to be a `BOOLEAN`")); } + } while(0); + do { // convert the 'MasterRepresentation' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->MasterRepresentation, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcTrimmedCurve to be a `IfcTrimmingPreference`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPresentationStyle>(const DB& db, const LIST& params, IfcPresentationStyle* in) +template <> size_t GenericFill<IfcRelDefines>(const DB& db, const LIST& params, IfcRelDefines* in) { - size_t base = 0; - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyle"); } do { // convert the 'Name' argument + size_t base = GenericFill(db,params,static_cast<IfcRelationship*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRelDefines"); } do { // convert the 'RelatedObjects' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcPresentationStyle,1>::aux_is_derived[0]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Name, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyle to be a `IfcLabel`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDefines,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->RelatedObjects, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDefines to be a `SET [1:?] OF IfcObject`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricHeaterType>(const DB& db, const LIST& params, IfcElectricHeaterType* in) +template <> size_t GenericFill<IfcRelDefinesByProperties>(const DB& db, const LIST& params, IfcRelDefinesByProperties* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcRelDefines*>(in)); + if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDefinesByProperties"); } do { // convert the 'RelatingPropertyDefinition' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDefinesByProperties,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->RelatingPropertyDefinition, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDefinesByProperties to be a `IfcPropertySetDefinition`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcActor>(const DB& db, const LIST& params, IfcActor* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBuildingStorey>(const DB& db, const LIST& params, IfcBuildingStorey* in) +template <> size_t GenericFill<IfcOccupant>(const DB& db, const LIST& params, IfcOccupant* in) { - size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcActor*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcVertex>(const DB& db, const LIST& params, IfcVertex* in) +template <> size_t GenericFill<IfcHumidifierType>(const DB& db, const LIST& params, IfcHumidifierType* in) { - size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcVertexPoint>(const DB& db, const LIST& params, IfcVertexPoint* in) +template <> size_t GenericFill<IfcArbitraryOpenProfileDef>(const DB& db, const LIST& params, IfcArbitraryOpenProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcVertex*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryOpenProfileDef"); } do { // convert the 'Curve' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcArbitraryOpenProfileDef,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Curve, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryOpenProfileDef to be a `IfcBoundedCurve`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcPermit>(const DB& db, const LIST& params, IfcPermit* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowInstrumentType>(const DB& db, const LIST& params, IfcFlowInstrumentType* in) +template <> size_t GenericFill<IfcOffsetCurve3D>(const DB& db, const LIST& params, IfcOffsetCurve3D* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcParameterizedProfileDef>(const DB& db, const LIST& params, IfcParameterizedProfileDef* in) +template <> size_t GenericFill<IfcLightSource>(const DB& db, const LIST& params, IfcLightSource* in) { - size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcParameterizedProfileDef"); } do { // convert the 'Position' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcParameterizedProfileDef,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Position, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcParameterizedProfileDef to be a `IfcAxis2Placement2D`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcUShapeProfileDef>(const DB& db, const LIST& params, IfcUShapeProfileDef* in) +template <> size_t GenericFill<IfcLightSourcePositional>(const DB& db, const LIST& params, IfcLightSourcePositional* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRamp>(const DB& db, const LIST& params, IfcRamp* in) +template <> size_t GenericFill<IfcCompositeProfileDef>(const DB& db, const LIST& params, IfcCompositeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCompositeCurve>(const DB& db, const LIST& params, IfcCompositeCurve* in) +template <> size_t GenericFill<IfcRamp>(const DB& db, const LIST& params, IfcRamp* in) { - size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCompositeCurve"); } do { // convert the 'Segments' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCompositeCurve,2>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Segments, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurve to be a `LIST [1:?] OF IfcCompositeCurveSegment`")); } - } while(0); - do { // convert the 'SelfIntersect' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCompositeCurve,2>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->SelfIntersect, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurve to be a `LOGICAL`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralCurveMemberVarying>(const DB& db, const LIST& params, IfcStructuralCurveMemberVarying* in) +template <> size_t GenericFill<IfcFlowMovingDevice>(const DB& db, const LIST& params, IfcFlowMovingDevice* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralCurveMember*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRampFlightType>(const DB& db, const LIST& params, IfcRampFlightType* in) +template <> size_t GenericFill<IfcSpaceHeaterType>(const DB& db, const LIST& params, IfcSpaceHeaterType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDraughtingCallout>(const DB& db, const LIST& params, IfcDraughtingCallout* in) +template <> size_t GenericFill<IfcLampType>(const DB& db, const LIST& params, IfcLampType* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDimensionCurveDirectedCallout>(const DB& db, const LIST& params, IfcDimensionCurveDirectedCallout* in) +template <> size_t GenericFill<IfcBuildingElementComponent>(const DB& db, const LIST& params, IfcBuildingElementComponent* in) { - size_t base = GenericFill(db,params,static_cast<IfcDraughtingCallout*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRadiusDimension>(const DB& db, const LIST& params, IfcRadiusDimension* in) +template <> size_t GenericFill<IfcReinforcingElement>(const DB& db, const LIST& params, IfcReinforcingElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementComponent*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEdgeFeature>(const DB& db, const LIST& params, IfcEdgeFeature* in) +template <> size_t GenericFill<IfcReinforcingBar>(const DB& db, const LIST& params, IfcReinforcingBar* in) { - size_t base = GenericFill(db,params,static_cast<IfcFeatureElementSubtraction*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSweptAreaSolid>(const DB& db, const LIST& params, IfcSweptAreaSolid* in) +template <> size_t GenericFill<IfcElectricHeaterType>(const DB& db, const LIST& params, IfcElectricHeaterType* in) { - size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcSweptAreaSolid"); } do { // convert the 'SweptArea' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSweptAreaSolid,2>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->SweptArea, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSweptAreaSolid to be a `IfcProfileDef`")); } - } while(0); - do { // convert the 'Position' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSweptAreaSolid,2>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->Position, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSweptAreaSolid to be a `IfcAxis2Placement3D`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcExtrudedAreaSolid>(const DB& db, const LIST& params, IfcExtrudedAreaSolid* in) +template <> size_t GenericFill<IfcTShapeProfileDef>(const DB& db, const LIST& params, IfcTShapeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcExtrudedAreaSolid"); } do { // convert the 'ExtrudedDirection' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->ExtrudedDirection, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcExtrudedAreaSolid to be a `IfcDirection`")); } - } while(0); - do { // convert the 'Depth' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Depth, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcExtrudedAreaSolid to be a `IfcPositiveLengthMeasure`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotationTextOccurrence>(const DB& db, const LIST& params, IfcAnnotationTextOccurrence* in) +template <> size_t GenericFill<IfcStructuralActivity>(const DB& db, const LIST& params, IfcStructuralActivity* in) { - size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStair>(const DB& db, const LIST& params, IfcStair* in) +template <> size_t GenericFill<IfcStructuralAction>(const DB& db, const LIST& params, IfcStructuralAction* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralActivity*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFillAreaStyleTileSymbolWithStyle>(const DB& db, const LIST& params, IfcFillAreaStyleTileSymbolWithStyle* in) +template <> size_t GenericFill<IfcDuctFittingType>(const DB& db, const LIST& params, IfcDuctFittingType* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotationSymbolOccurrence>(const DB& db, const LIST& params, IfcAnnotationSymbolOccurrence* in) +template <> size_t GenericFill<IfcCartesianTransformationOperator2D>(const DB& db, const LIST& params, IfcCartesianTransformationOperator2D* in) { - size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTerminatorSymbol>(const DB& db, const LIST& params, IfcTerminatorSymbol* in) +template <> size_t GenericFill<IfcCartesianTransformationOperator2DnonUniform>(const DB& db, const LIST& params, IfcCartesianTransformationOperator2DnonUniform* in) { - size_t base = GenericFill(db,params,static_cast<IfcAnnotationSymbolOccurrence*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator2D*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDimensionCurveTerminator>(const DB& db, const LIST& params, IfcDimensionCurveTerminator* in) +template <> size_t GenericFill<IfcVirtualElement>(const DB& db, const LIST& params, IfcVirtualElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcTerminatorSymbol*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRectangleProfileDef>(const DB& db, const LIST& params, IfcRectangleProfileDef* in) +template <> size_t GenericFill<IfcRightCircularCylinder>(const DB& db, const LIST& params, IfcRightCircularCylinder* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); - if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcRectangleProfileDef"); } do { // convert the 'XDim' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRectangleProfileDef,2>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->XDim, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); } - } while(0); - do { // convert the 'YDim' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRectangleProfileDef,2>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->YDim, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRectangleProfileDef to be a `IfcPositiveLengthMeasure`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRectangleHollowProfileDef>(const DB& db, const LIST& params, IfcRectangleHollowProfileDef* in) +template <> size_t GenericFill<IfcOutletType>(const DB& db, const LIST& params, IfcOutletType* in) { - size_t base = GenericFill(db,params,static_cast<IfcRectangleProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLocalPlacement>(const DB& db, const LIST& params, IfcLocalPlacement* in) +template <> size_t GenericFill<IfcRelDecomposes>(const DB& db, const LIST& params, IfcRelDecomposes* in) { - size_t base = GenericFill(db,params,static_cast<IfcObjectPlacement*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLocalPlacement"); } do { // convert the 'PlacementRelTo' argument + size_t base = GenericFill(db,params,static_cast<IfcRelationship*>(in)); + if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDecomposes"); } do { // convert the 'RelatingObject' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->PlacementRelTo, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLocalPlacement to be a `IfcObjectPlacement`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDecomposes,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->RelatingObject, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDecomposes to be a `IfcObjectDefinition`")); } } while(0); - do { // convert the 'RelativePlacement' argument + do { // convert the 'RelatedObjects' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->RelativePlacement, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLocalPlacement to be a `IfcAxis2Placement`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDecomposes,2>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->RelatedObjects, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDecomposes to be a `SET [1:?] OF IfcObjectDefinition`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTask>(const DB& db, const LIST& params, IfcTask* in) +template <> size_t GenericFill<IfcCovering>(const DB& db, const LIST& params, IfcCovering* in) { - size_t base = GenericFill(db,params,static_cast<IfcProcess*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotationFillAreaOccurrence>(const DB& db, const LIST& params, IfcAnnotationFillAreaOccurrence* in) +template <> size_t GenericFill<IfcPolyline>(const DB& db, const LIST& params, IfcPolyline* in) { - size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyline"); } do { // convert the 'Points' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Points, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyline to be a `LIST [2:?] OF IfcCartesianPoint`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFace>(const DB& db, const LIST& params, IfcFace* in) +template <> size_t GenericFill<IfcPath>(const DB& db, const LIST& params, IfcPath* in) { size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFace"); } do { // convert the 'Bounds' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFace,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Bounds, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFace to be a `SET [1:?] OF IfcFaceBound`")); } - } while(0); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowSegmentType>(const DB& db, const LIST& params, IfcFlowSegmentType* in) +template <> size_t GenericFill<IfcElementComponent>(const DB& db, const LIST& params, IfcElementComponent* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDuctSegmentType>(const DB& db, const LIST& params, IfcDuctSegmentType* in) +template <> size_t GenericFill<IfcFastener>(const DB& db, const LIST& params, IfcFastener* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElementComponent*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcConstructionResource>(const DB& db, const LIST& params, IfcConstructionResource* in) +template <> size_t GenericFill<IfcMappedItem>(const DB& db, const LIST& params, IfcMappedItem* in) { - size_t base = GenericFill(db,params,static_cast<IfcResource*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMappedItem"); } do { // convert the 'MappingSource' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->MappingSource, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMappedItem to be a `IfcRepresentationMap`")); } + } while(0); + do { // convert the 'MappingTarget' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->MappingTarget, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMappedItem to be a `IfcCartesianTransformationOperator`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcConstructionEquipmentResource>(const DB& db, const LIST& params, IfcConstructionEquipmentResource* in) +template <> size_t GenericFill<IfcRectangularPyramid>(const DB& db, const LIST& params, IfcRectangularPyramid* in) { - size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSanitaryTerminalType>(const DB& db, const LIST& params, IfcSanitaryTerminalType* in) +template <> size_t GenericFill<IfcCrewResource>(const DB& db, const LIST& params, IfcCrewResource* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCircleProfileDef>(const DB& db, const LIST& params, IfcCircleProfileDef* in) +template <> size_t GenericFill<IfcNamedUnit>(const DB& db, const LIST& params, IfcNamedUnit* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCircleProfileDef"); } do { // convert the 'Radius' argument + size_t base = 0; + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcNamedUnit"); } do { // convert the 'Dimensions' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCircleProfileDef,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Radius, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCircleProfileDef to be a `IfcPositiveLengthMeasure`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcNamedUnit,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Dimensions, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcNamedUnit to be a `IfcDimensionalExponents`")); } + } while(0); + do { // convert the 'UnitType' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcNamedUnit,2>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->UnitType, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcNamedUnit to be a `IfcUnitEnum`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralReaction>(const DB& db, const LIST& params, IfcStructuralReaction* in) +template <> size_t GenericFill<IfcContextDependentUnit>(const DB& db, const LIST& params, IfcContextDependentUnit* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralActivity*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralPointReaction>(const DB& db, const LIST& params, IfcStructuralPointReaction* in) +template <> size_t GenericFill<IfcUnitaryEquipmentType>(const DB& db, const LIST& params, IfcUnitaryEquipmentType* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralReaction*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRailing>(const DB& db, const LIST& params, IfcRailing* in) +template <> size_t GenericFill<IfcRoof>(const DB& db, const LIST& params, IfcRoof* in) { size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTextLiteral>(const DB& db, const LIST& params, IfcTextLiteral* in) +template <> size_t GenericFill<IfcStructuralMember>(const DB& db, const LIST& params, IfcStructuralMember* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCartesianTransformationOperator>(const DB& db, const LIST& params, IfcCartesianTransformationOperator* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCartesianTransformationOperator"); } do { // convert the 'Axis1' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[0]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Axis1, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianTransformationOperator to be a `IfcDirection`")); } - } while(0); - do { // convert the 'Axis2' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[1]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Axis2, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCartesianTransformationOperator to be a `IfcDirection`")); } - } while(0); - do { // convert the 'LocalOrigin' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[2]=true; break; } - try { GenericConvert( in->LocalOrigin, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCartesianTransformationOperator to be a `IfcCartesianPoint`")); } - } while(0); - do { // convert the 'Scale' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator,4>::aux_is_derived[3]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Scale, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCartesianTransformationOperator to be a `REAL`")); } - } while(0); - return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLinearDimension>(const DB& db, const LIST& params, IfcLinearDimension* in) +template <> size_t GenericFill<IfcStyleModel>(const DB& db, const LIST& params, IfcStyleModel* in) { - size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcRepresentation*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDamperType>(const DB& db, const LIST& params, IfcDamperType* in) +template <> size_t GenericFill<IfcStyledRepresentation>(const DB& db, const LIST& params, IfcStyledRepresentation* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStyleModel*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSIUnit>(const DB& db, const LIST& params, IfcSIUnit* in) +template <> size_t GenericFill<IfcSpatialStructureElement>(const DB& db, const LIST& params, IfcSpatialStructureElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcSIUnit"); } do { // convert the 'Prefix' argument + size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); + if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcSpatialStructureElement"); } do { // convert the 'LongName' argument boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSpatialStructureElement,2>::aux_is_derived[0]=true; break; } if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Prefix, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSIUnit to be a `IfcSIPrefix`")); } + try { GenericConvert( in->LongName, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSpatialStructureElement to be a `IfcLabel`")); } } while(0); - do { // convert the 'Name' argument + do { // convert the 'CompositionType' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Name, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSIUnit to be a `IfcSIUnitName`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSpatialStructureElement,2>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->CompositionType, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSpatialStructureElement to be a `IfcElementCompositionEnum`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMeasureWithUnit>(const DB& db, const LIST& params, IfcMeasureWithUnit* in) +template <> size_t GenericFill<IfcBuilding>(const DB& db, const LIST& params, IfcBuilding* in) { - size_t base = 0; - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMeasureWithUnit"); } do { // convert the 'ValueComponent' argument + size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in)); + if (params.GetSize() < 12) { throw STEP::TypeError("expected 12 arguments to IfcBuilding"); } do { // convert the 'ElevationOfRefHeight' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->ValueComponent, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMeasureWithUnit to be a `IfcValue`")); } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ElevationOfRefHeight, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcBuilding to be a `IfcLengthMeasure`")); } } while(0); - do { // convert the 'UnitComponent' argument + do { // convert the 'ElevationOfTerrain' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->UnitComponent, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMeasureWithUnit to be a `IfcUnit`")); } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ElevationOfTerrain, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcBuilding to be a `IfcLengthMeasure`")); } + } while(0); + do { // convert the 'BuildingAddress' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->BuildingAddress, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcBuilding to be a `IfcPostalAddress`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionElement>(const DB& db, const LIST& params, IfcDistributionElement* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members - return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionControlElement>(const DB& db, const LIST& params, IfcDistributionControlElement* in) +template <> size_t GenericFill<IfcConnectedFaceSet>(const DB& db, const LIST& params, IfcConnectedFaceSet* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConnectedFaceSet"); } do { // convert the 'CfsFaces' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcConnectedFaceSet,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->CfsFaces, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConnectedFaceSet to be a `SET [1:?] OF IfcFace`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTransformerType>(const DB& db, const LIST& params, IfcTransformerType* in) +template <> size_t GenericFill<IfcOpenShell>(const DB& db, const LIST& params, IfcOpenShell* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcConnectedFaceSet*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLaborResource>(const DB& db, const LIST& params, IfcLaborResource* in) +template <> size_t GenericFill<IfcFacetedBrep>(const DB& db, const LIST& params, IfcFacetedBrep* in) { - size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcManifoldSolidBrep*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDerivedProfileDef>(const DB& db, const LIST& params, IfcDerivedProfileDef* in) +template <> size_t GenericFill<IfcConic>(const DB& db, const LIST& params, IfcConic* in) { - size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcConic"); } do { // convert the 'Position' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcConic,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Position, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcConic to be a `IfcAxis2Placement`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFurnitureStandard>(const DB& db, const LIST& params, IfcFurnitureStandard* in) +template <> size_t GenericFill<IfcCoveringType>(const DB& db, const LIST& params, IfcCoveringType* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStairFlightType>(const DB& db, const LIST& params, IfcStairFlightType* in) +template <> size_t GenericFill<IfcRoundedRectangleProfileDef>(const DB& db, const LIST& params, IfcRoundedRectangleProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcRectangleProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWorkControl>(const DB& db, const LIST& params, IfcWorkControl* in) +template <> size_t GenericFill<IfcAirTerminalType>(const DB& db, const LIST& params, IfcAirTerminalType* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWorkPlan>(const DB& db, const LIST& params, IfcWorkPlan* in) +template <> size_t GenericFill<IfcFlowMovingDeviceType>(const DB& db, const LIST& params, IfcFlowMovingDeviceType* in) { - size_t base = GenericFill(db,params,static_cast<IfcWorkControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCondition>(const DB& db, const LIST& params, IfcCondition* in) +template <> size_t GenericFill<IfcCompressorType>(const DB& db, const LIST& params, IfcCompressorType* in) { - size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRelVoidsElement>(const DB& db, const LIST& params, IfcRelVoidsElement* in) +template <> size_t GenericFill<IfcIShapeProfileDef>(const DB& db, const LIST& params, IfcIShapeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in)); - if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelVoidsElement"); } do { // convert the 'RelatingBuildingElement' argument + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcIShapeProfileDef"); } do { // convert the 'OverallWidth' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->RelatingBuildingElement, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelVoidsElement to be a `IfcElement`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->OverallWidth, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); } } while(0); - do { // convert the 'RelatedOpeningElement' argument + do { // convert the 'OverallDepth' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->RelatedOpeningElement, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelVoidsElement to be a `IfcFeatureElementSubtraction`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->OverallDepth, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'WebThickness' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[2]=true; break; } + try { GenericConvert( in->WebThickness, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'FlangeThickness' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[3]=true; break; } + try { GenericConvert( in->FlangeThickness, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'FilletRadius' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcIShapeProfileDef,5>::aux_is_derived[4]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->FilletRadius, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcIShapeProfileDef to be a `IfcPositiveLengthMeasure`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWindow>(const DB& db, const LIST& params, IfcWindow* in) +template <> size_t GenericFill<IfcAsymmetricIShapeProfileDef>(const DB& db, const LIST& params, IfcAsymmetricIShapeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcIShapeProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProtectiveDeviceType>(const DB& db, const LIST& params, IfcProtectiveDeviceType* in) +template <> size_t GenericFill<IfcControllerType>(const DB& db, const LIST& params, IfcControllerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcJunctionBoxType>(const DB& db, const LIST& params, IfcJunctionBoxType* in) +template <> size_t GenericFill<IfcRailing>(const DB& db, const LIST& params, IfcRailing* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralAnalysisModel>(const DB& db, const LIST& params, IfcStructuralAnalysisModel* in) +template <> size_t GenericFill<IfcGroup>(const DB& db, const LIST& params, IfcGroup* in) { - size_t base = GenericFill(db,params,static_cast<IfcSystem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAxis2Placement2D>(const DB& db, const LIST& params, IfcAxis2Placement2D* in) +template <> size_t GenericFill<IfcAsset>(const DB& db, const LIST& params, IfcAsset* in) { - size_t base = GenericFill(db,params,static_cast<IfcPlacement*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis2Placement2D"); } do { // convert the 'RefDirection' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->RefDirection, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement2D to be a `IfcDirection`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSpaceType>(const DB& db, const LIST& params, IfcSpaceType* in) +template <> size_t GenericFill<IfcMaterialDefinitionRepresentation>(const DB& db, const LIST& params, IfcMaterialDefinitionRepresentation* in) { - size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProductRepresentation*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEllipseProfileDef>(const DB& db, const LIST& params, IfcEllipseProfileDef* in) +template <> size_t GenericFill<IfcRailingType>(const DB& db, const LIST& params, IfcRailingType* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionFlowElement>(const DB& db, const LIST& params, IfcDistributionFlowElement* in) +template <> size_t GenericFill<IfcWall>(const DB& db, const LIST& params, IfcWall* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowMovingDevice>(const DB& db, const LIST& params, IfcFlowMovingDevice* in) +template <> size_t GenericFill<IfcStructuralPointConnection>(const DB& db, const LIST& params, IfcStructuralPointConnection* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSurfaceStyleWithTextures>(const DB& db, const LIST& params, IfcSurfaceStyleWithTextures* in) +template <> size_t GenericFill<IfcPropertyListValue>(const DB& db, const LIST& params, IfcPropertyListValue* in) { - size_t base = 0; - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleWithTextures"); } do { // convert the 'Textures' argument + size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertyListValue"); } do { // convert the 'ListValues' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Textures, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleWithTextures to be a `LIST [1:?] OF IfcSurfaceTexture`")); } + try { GenericConvert( in->ListValues, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPropertyListValue to be a `LIST [1:?] OF IfcValue`")); } + } while(0); + do { // convert the 'Unit' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Unit, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPropertyListValue to be a `IfcUnit`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGeometricSet>(const DB& db, const LIST& params, IfcGeometricSet* in) +template <> size_t GenericFill<IfcFurnitureStandard>(const DB& db, const LIST& params, IfcFurnitureStandard* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProjectOrder>(const DB& db, const LIST& params, IfcProjectOrder* in) +template <> size_t GenericFill<IfcElectricGeneratorType>(const DB& db, const LIST& params, IfcElectricGeneratorType* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBSplineCurve>(const DB& db, const LIST& params, IfcBSplineCurve* in) +template <> size_t GenericFill<IfcDoor>(const DB& db, const LIST& params, IfcDoor* in) { - size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in)); - if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcBSplineCurve"); } do { // convert the 'Degree' argument + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + if (params.GetSize() < 10) { throw STEP::TypeError("expected 10 arguments to IfcDoor"); } do { // convert the 'OverallHeight' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Degree, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBSplineCurve to be a `INTEGER`")); } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->OverallHeight, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcDoor to be a `IfcPositiveLengthMeasure`")); } } while(0); - do { // convert the 'ControlPointsList' argument + do { // convert the 'OverallWidth' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->ControlPointsList, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBSplineCurve to be a `LIST [2:?] OF IfcCartesianPoint`")); } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->OverallWidth, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcDoor to be a `IfcPositiveLengthMeasure`")); } } while(0); - do { // convert the 'CurveForm' argument + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcStyledItem>(const DB& db, const LIST& params, IfcStyledItem* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcStyledItem"); } do { // convert the 'Item' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[2]=true; break; } - try { GenericConvert( in->CurveForm, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBSplineCurve to be a `IfcBSplineCurveForm`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Item, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcStyledItem to be a `IfcRepresentationItem`")); } } while(0); - do { // convert the 'ClosedCurve' argument + do { // convert the 'Styles' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[3]=true; break; } - try { GenericConvert( in->ClosedCurve, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBSplineCurve to be a `LOGICAL`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->Styles, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcStyledItem to be a `SET [1:?] OF IfcPresentationStyleAssignment`")); } } while(0); - do { // convert the 'SelfIntersect' argument + do { // convert the 'Name' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[4]=true; break; } - try { GenericConvert( in->SelfIntersect, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcBSplineCurve to be a `LOGICAL`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcStyledItem,3>::aux_is_derived[2]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Name, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcStyledItem to be a `IfcLabel`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBezierCurve>(const DB& db, const LIST& params, IfcBezierCurve* in) +template <> size_t GenericFill<IfcAnnotationOccurrence>(const DB& db, const LIST& params, IfcAnnotationOccurrence* in) { - size_t base = GenericFill(db,params,static_cast<IfcBSplineCurve*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStyledItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralPointConnection>(const DB& db, const LIST& params, IfcStructuralPointConnection* in) +template <> size_t GenericFill<IfcAnnotationSymbolOccurrence>(const DB& db, const LIST& params, IfcAnnotationSymbolOccurrence* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowController>(const DB& db, const LIST& params, IfcFlowController* in) +template <> size_t GenericFill<IfcArbitraryClosedProfileDef>(const DB& db, const LIST& params, IfcArbitraryClosedProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryClosedProfileDef"); } do { // convert the 'OuterCurve' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcArbitraryClosedProfileDef,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->OuterCurve, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryClosedProfileDef to be a `IfcCurve`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricDistributionPoint>(const DB& db, const LIST& params, IfcElectricDistributionPoint* in) +template <> size_t GenericFill<IfcArbitraryProfileDefWithVoids>(const DB& db, const LIST& params, IfcArbitraryProfileDefWithVoids* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowController*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcArbitraryClosedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSite>(const DB& db, const LIST& params, IfcSite* in) +template <> size_t GenericFill<IfcLine>(const DB& db, const LIST& params, IfcLine* in) { - size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in)); - if (params.GetSize() < 14) { throw STEP::TypeError("expected 14 arguments to IfcSite"); } do { // convert the 'RefLatitude' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->RefLatitude, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); } - } while(0); - do { // convert the 'RefLongitude' argument + size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcLine"); } do { // convert the 'Pnt' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->RefLongitude, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); } + try { GenericConvert( in->Pnt, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcLine to be a `IfcCartesianPoint`")); } } while(0); - do { // convert the 'RefElevation' argument + do { // convert the 'Dir' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->RefElevation, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcSite to be a `IfcLengthMeasure`")); } + try { GenericConvert( in->Dir, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcLine to be a `IfcVector`")); } } while(0); - do { // convert the 'LandTitleNumber' argument + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcFlowSegmentType>(const DB& db, const LIST& params, IfcFlowSegmentType* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcAirTerminalBoxType>(const DB& db, const LIST& params, IfcAirTerminalBoxType* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcPropertySingleValue>(const DB& db, const LIST& params, IfcPropertySingleValue* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcPropertySingleValue"); } do { // convert the 'NominalValue' argument boost::shared_ptr<const DataType> arg = params[base++]; if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->LandTitleNumber, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 12 to IfcSite to be a `IfcLabel`")); } + try { GenericConvert( in->NominalValue, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcPropertySingleValue to be a `IfcValue`")); } } while(0); - do { // convert the 'SiteAddress' argument + do { // convert the 'Unit' argument boost::shared_ptr<const DataType> arg = params[base++]; if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->SiteAddress, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 13 to IfcSite to be a `IfcPostalAddress`")); } + try { GenericConvert( in->Unit, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcPropertySingleValue to be a `IfcUnit`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOffsetCurve3D>(const DB& db, const LIST& params, IfcOffsetCurve3D* in) +template <> size_t GenericFill<IfcAlarmType>(const DB& db, const LIST& params, IfcAlarmType* in) { - size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcVirtualElement>(const DB& db, const LIST& params, IfcVirtualElement* in) +template <> size_t GenericFill<IfcEllipseProfileDef>(const DB& db, const LIST& params, IfcEllipseProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcConstructionProductResource>(const DB& db, const LIST& params, IfcConstructionProductResource* in) +template <> size_t GenericFill<IfcStair>(const DB& db, const LIST& params, IfcStair* in) { - size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSurfaceCurveSweptAreaSolid>(const DB& db, const LIST& params, IfcSurfaceCurveSweptAreaSolid* in) +template <> size_t GenericFill<IfcSurfaceStyleShading>(const DB& db, const LIST& params, IfcSurfaceStyleShading* in) { - size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in)); + size_t base = 0; + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleShading"); } do { // convert the 'SurfaceColour' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSurfaceStyleShading,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->SurfaceColour, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleShading to be a `IfcColourRgb`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcPumpType>(const DB& db, const LIST& params, IfcPumpType* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCartesianTransformationOperator3D>(const DB& db, const LIST& params, IfcCartesianTransformationOperator3D* in) +template <> size_t GenericFill<IfcDefinedSymbol>(const DB& db, const LIST& params, IfcDefinedSymbol* in) { - size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator*>(in)); - if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCartesianTransformationOperator3D"); } do { // convert the 'Axis3' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcCartesianTransformationOperator3D,1>::aux_is_derived[0]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Axis3, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCartesianTransformationOperator3D to be a `IfcDirection`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCartesianTransformationOperator3DnonUniform>(const DB& db, const LIST& params, IfcCartesianTransformationOperator3DnonUniform* in) +template <> size_t GenericFill<IfcElementComponentType>(const DB& db, const LIST& params, IfcElementComponentType* in) { - size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator3D*>(in)); - if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcCartesianTransformationOperator3DnonUniform"); } do { // convert the 'Scale2' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Scale2, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); } - } while(0); - do { // convert the 'Scale3' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Scale3, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCrewResource>(const DB& db, const LIST& params, IfcCrewResource* in) +template <> size_t GenericFill<IfcFastenerType>(const DB& db, const LIST& params, IfcFastenerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElementComponentType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralSurfaceMember>(const DB& db, const LIST& params, IfcStructuralSurfaceMember* in) +template <> size_t GenericFill<IfcMechanicalFastenerType>(const DB& db, const LIST& params, IfcMechanicalFastenerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralMember*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFastenerType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<Ifc2DCompositeCurve>(const DB& db, const LIST& params, Ifc2DCompositeCurve* in) +template <> size_t GenericFill<IfcFlowFitting>(const DB& db, const LIST& params, IfcFlowFitting* in) { - size_t base = GenericFill(db,params,static_cast<IfcCompositeCurve*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRepresentationContext>(const DB& db, const LIST& params, IfcRepresentationContext* in) +template <> size_t GenericFill<IfcLightSourceDirectional>(const DB& db, const LIST& params, IfcLightSourceDirectional* in) { - size_t base = 0; - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationContext"); } do { // convert the 'ContextIdentifier' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentationContext,2>::aux_is_derived[0]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ContextIdentifier, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationContext to be a `IfcLabel`")); } - } while(0); - do { // convert the 'ContextType' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentationContext,2>::aux_is_derived[1]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ContextType, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationContext to be a `IfcLabel`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGeometricRepresentationContext>(const DB& db, const LIST& params, IfcGeometricRepresentationContext* in) +template <> size_t GenericFill<IfcSurfaceStyle>(const DB& db, const LIST& params, IfcSurfaceStyle* in) { - size_t base = GenericFill(db,params,static_cast<IfcRepresentationContext*>(in)); - if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcGeometricRepresentationContext"); } do { // convert the 'CoordinateSpaceDimension' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->CoordinateSpaceDimension, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcGeometricRepresentationContext to be a `IfcDimensionCount`")); } - } while(0); - do { // convert the 'Precision' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[1]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Precision, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcGeometricRepresentationContext to be a `REAL`")); } - } while(0); - do { // convert the 'WorldCoordinateSystem' argument + size_t base = GenericFill(db,params,static_cast<IfcPresentationStyle*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcSurfaceStyle"); } do { // convert the 'Side' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[2]=true; break; } - try { GenericConvert( in->WorldCoordinateSystem, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcGeometricRepresentationContext to be a `IfcAxis2Placement`")); } + try { GenericConvert( in->Side, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyle to be a `IfcSurfaceSide`")); } } while(0); - do { // convert the 'TrueNorth' argument + do { // convert the 'Styles' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[3]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->TrueNorth, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcGeometricRepresentationContext to be a `IfcDirection`")); } + try { GenericConvert( in->Styles, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyle to be a `SET [1:5] OF IfcSurfaceStyleElementSelect`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowTreatmentDevice>(const DB& db, const LIST& params, IfcFlowTreatmentDevice* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members - return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRightCircularCylinder>(const DB& db, const LIST& params, IfcRightCircularCylinder* in) +template <> size_t GenericFill<IfcAnnotationSurface>(const DB& db, const LIST& params, IfcAnnotationSurface* in) { - size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWasteTerminalType>(const DB& db, const LIST& params, IfcWasteTerminalType* in) +template <> size_t GenericFill<IfcFlowController>(const DB& db, const LIST& params, IfcFlowController* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBuildingElementComponent>(const DB& db, const LIST& params, IfcBuildingElementComponent* in) +template <> size_t GenericFill<IfcBuildingStorey>(const DB& db, const LIST& params, IfcBuildingStorey* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBuildingElementPart>(const DB& db, const LIST& params, IfcBuildingElementPart* in) +template <> size_t GenericFill<IfcWorkControl>(const DB& db, const LIST& params, IfcWorkControl* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementComponent*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWall>(const DB& db, const LIST& params, IfcWall* in) +template <> size_t GenericFill<IfcWorkSchedule>(const DB& db, const LIST& params, IfcWorkSchedule* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcWorkControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWallStandardCase>(const DB& db, const LIST& params, IfcWallStandardCase* in) +template <> size_t GenericFill<IfcDuctSegmentType>(const DB& db, const LIST& params, IfcDuctSegmentType* in) { - size_t base = GenericFill(db,params,static_cast<IfcWall*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPath>(const DB& db, const LIST& params, IfcPath* in) +template <> size_t GenericFill<IfcFace>(const DB& db, const LIST& params, IfcFace* in) { size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFace"); } do { // convert the 'Bounds' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFace,1>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Bounds, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFace to be a `SET [1:?] OF IfcFaceBound`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDefinedSymbol>(const DB& db, const LIST& params, IfcDefinedSymbol* in) +template <> size_t GenericFill<IfcStructuralSurfaceMember>(const DB& db, const LIST& params, IfcStructuralSurfaceMember* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralMember*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } @@ -3102,119 +3245,94 @@ template <> size_t GenericFill<IfcStructuralSurfaceMemberVarying>(const DB& db, return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPoint>(const DB& db, const LIST& params, IfcPoint* in) +template <> size_t GenericFill<IfcFaceSurface>(const DB& db, const LIST& params, IfcFaceSurface* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFace*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSurfaceOfRevolution>(const DB& db, const LIST& params, IfcSurfaceOfRevolution* in) +template <> size_t GenericFill<IfcCostSchedule>(const DB& db, const LIST& params, IfcCostSchedule* in) { - size_t base = GenericFill(db,params,static_cast<IfcSweptSurface*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowTerminal>(const DB& db, const LIST& params, IfcFlowTerminal* in) +template <> size_t GenericFill<IfcPlanarExtent>(const DB& db, const LIST& params, IfcPlanarExtent* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFurnishingElement>(const DB& db, const LIST& params, IfcFurnishingElement* in) +template <> size_t GenericFill<IfcPlanarBox>(const DB& db, const LIST& params, IfcPlanarBox* in) { - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcPlanarExtent*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSurfaceStyleShading>(const DB& db, const LIST& params, IfcSurfaceStyleShading* in) +template <> size_t GenericFill<IfcColourSpecification>(const DB& db, const LIST& params, IfcColourSpecification* in) { size_t base = 0; - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleShading"); } do { // convert the 'SurfaceColour' argument + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcColourSpecification"); } do { // convert the 'Name' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcSurfaceStyleShading,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->SurfaceColour, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleShading to be a `IfcColourRgb`")); } + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcColourSpecification,1>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Name, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcColourSpecification to be a `IfcLabel`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSurfaceStyleRendering>(const DB& db, const LIST& params, IfcSurfaceStyleRendering* in) +template <> size_t GenericFill<IfcVector>(const DB& db, const LIST& params, IfcVector* in) { - size_t base = GenericFill(db,params,static_cast<IfcSurfaceStyleShading*>(in)); - if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcSurfaceStyleRendering"); } do { // convert the 'Transparency' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Transparency, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyleRendering to be a `IfcNormalisedRatioMeasure`")); } - } while(0); - do { // convert the 'DiffuseColour' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->DiffuseColour, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } - } while(0); - do { // convert the 'TransmissionColour' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->TransmissionColour, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } - } while(0); - do { // convert the 'DiffuseTransmissionColour' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->DiffuseTransmissionColour, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } - } while(0); - do { // convert the 'ReflectionColour' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ReflectionColour, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } - } while(0); - do { // convert the 'SpecularColour' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->SpecularColour, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } - } while(0); - do { // convert the 'SpecularHighlight' argument + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcVector"); } do { // convert the 'Orientation' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->SpecularHighlight, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSurfaceStyleRendering to be a `IfcSpecularHighlightSelect`")); } + try { GenericConvert( in->Orientation, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcVector to be a `IfcDirection`")); } } while(0); - do { // convert the 'ReflectanceMethod' argument + do { // convert the 'Magnitude' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->ReflectanceMethod, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSurfaceStyleRendering to be a `IfcReflectanceMethodEnum`")); } + try { GenericConvert( in->Magnitude, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcVector to be a `IfcLengthMeasure`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCircleHollowProfileDef>(const DB& db, const LIST& params, IfcCircleHollowProfileDef* in) +template <> size_t GenericFill<IfcBeam>(const DB& db, const LIST& params, IfcBeam* in) { - size_t base = GenericFill(db,params,static_cast<IfcCircleProfileDef*>(in)); - if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCircleHollowProfileDef"); } do { // convert the 'WallThickness' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->WallThickness, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCircleHollowProfileDef to be a `IfcPositiveLengthMeasure`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowMovingDeviceType>(const DB& db, const LIST& params, IfcFlowMovingDeviceType* in) +template <> size_t GenericFill<IfcColourRgb>(const DB& db, const LIST& params, IfcColourRgb* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcColourSpecification*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcColourRgb"); } do { // convert the 'Red' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Red, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); } + } while(0); + do { // convert the 'Green' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Green, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); } + } while(0); + do { // convert the 'Blue' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Blue, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFanType>(const DB& db, const LIST& params, IfcFanType* in) +template <> size_t GenericFill<IfcStructuralPlanarAction>(const DB& db, const LIST& params, IfcStructuralPlanarAction* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } @@ -3226,966 +3344,1084 @@ template <> size_t GenericFill<IfcStructuralPlanarActionVarying>(const DB& db, c return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProductRepresentation>(const DB& db, const LIST& params, IfcProductRepresentation* in) +template <> size_t GenericFill<IfcSite>(const DB& db, const LIST& params, IfcSite* in) { - size_t base = 0; - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcProductRepresentation"); } do { // convert the 'Name' argument + size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in)); + if (params.GetSize() < 14) { throw STEP::TypeError("expected 14 arguments to IfcSite"); } do { // convert the 'RefLatitude' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[0]=true; break; } if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Name, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcProductRepresentation to be a `IfcLabel`")); } + try { GenericConvert( in->RefLatitude, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); } } while(0); - do { // convert the 'Description' argument + do { // convert the 'RefLongitude' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[1]=true; break; } if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Description, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcProductRepresentation to be a `IfcText`")); } + try { GenericConvert( in->RefLongitude, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSite to be a `IfcCompoundPlaneAngleMeasure`")); } } while(0); - do { // convert the 'Representations' argument + do { // convert the 'RefElevation' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcProductRepresentation,3>::aux_is_derived[2]=true; break; } - try { GenericConvert( in->Representations, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcProductRepresentation to be a `LIST [1:?] OF IfcRepresentation`")); } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->RefElevation, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcSite to be a `IfcLengthMeasure`")); } + } while(0); + do { // convert the 'LandTitleNumber' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->LandTitleNumber, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 12 to IfcSite to be a `IfcLabel`")); } + } while(0); + do { // convert the 'SiteAddress' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->SiteAddress, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 13 to IfcSite to be a `IfcPostalAddress`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStackTerminalType>(const DB& db, const LIST& params, IfcStackTerminalType* in) +template <> size_t GenericFill<IfcDiscreteAccessoryType>(const DB& db, const LIST& params, IfcDiscreteAccessoryType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElementComponentType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcReinforcingElement>(const DB& db, const LIST& params, IfcReinforcingElement* in) +template <> size_t GenericFill<IfcVibrationIsolatorType>(const DB& db, const LIST& params, IfcVibrationIsolatorType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementComponent*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDiscreteAccessoryType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcReinforcingMesh>(const DB& db, const LIST& params, IfcReinforcingMesh* in) +template <> size_t GenericFill<IfcEvaporativeCoolerType>(const DB& db, const LIST& params, IfcEvaporativeCoolerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOrderAction>(const DB& db, const LIST& params, IfcOrderAction* in) +template <> size_t GenericFill<IfcDistributionChamberElementType>(const DB& db, const LIST& params, IfcDistributionChamberElementType* in) { - size_t base = GenericFill(db,params,static_cast<IfcTask*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLightSource>(const DB& db, const LIST& params, IfcLightSource* in) +template <> size_t GenericFill<IfcFeatureElementAddition>(const DB& db, const LIST& params, IfcFeatureElementAddition* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFeatureElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLightSourceDirectional>(const DB& db, const LIST& params, IfcLightSourceDirectional* in) +template <> size_t GenericFill<IfcStructuredDimensionCallout>(const DB& db, const LIST& params, IfcStructuredDimensionCallout* in) { - size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDraughtingCallout*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLoop>(const DB& db, const LIST& params, IfcLoop* in) +template <> size_t GenericFill<IfcCoolingTowerType>(const DB& db, const LIST& params, IfcCoolingTowerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcVertexLoop>(const DB& db, const LIST& params, IfcVertexLoop* in) +template <> size_t GenericFill<IfcCenterLineProfileDef>(const DB& db, const LIST& params, IfcCenterLineProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcArbitraryOpenProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcChamferEdgeFeature>(const DB& db, const LIST& params, IfcChamferEdgeFeature* in) +template <> size_t GenericFill<IfcWindowStyle>(const DB& db, const LIST& params, IfcWindowStyle* in) { - size_t base = GenericFill(db,params,static_cast<IfcEdgeFeature*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcTypeProduct*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElementComponentType>(const DB& db, const LIST& params, IfcElementComponentType* in) +template <> size_t GenericFill<IfcLightSourceGoniometric>(const DB& db, const LIST& params, IfcLightSourceGoniometric* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFastenerType>(const DB& db, const LIST& params, IfcFastenerType* in) +template <> size_t GenericFill<IfcTransformerType>(const DB& db, const LIST& params, IfcTransformerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementComponentType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMechanicalFastenerType>(const DB& db, const LIST& params, IfcMechanicalFastenerType* in) +template <> size_t GenericFill<IfcMemberType>(const DB& db, const LIST& params, IfcMemberType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFastenerType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcScheduleTimeControl>(const DB& db, const LIST& params, IfcScheduleTimeControl* in) +template <> size_t GenericFill<IfcSurfaceOfLinearExtrusion>(const DB& db, const LIST& params, IfcSurfaceOfLinearExtrusion* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSweptSurface*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSurfaceStyle>(const DB& db, const LIST& params, IfcSurfaceStyle* in) +template <> size_t GenericFill<IfcMotorConnectionType>(const DB& db, const LIST& params, IfcMotorConnectionType* in) { - size_t base = GenericFill(db,params,static_cast<IfcPresentationStyle*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcSurfaceStyle"); } do { // convert the 'Side' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Side, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyle to be a `IfcSurfaceSide`")); } - } while(0); - do { // convert the 'Styles' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Styles, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyle to be a `SET [1:5] OF IfcSurfaceStyleElementSelect`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOpenShell>(const DB& db, const LIST& params, IfcOpenShell* in) +template <> size_t GenericFill<IfcFlowTreatmentDeviceType>(const DB& db, const LIST& params, IfcFlowTreatmentDeviceType* in) { - size_t base = GenericFill(db,params,static_cast<IfcConnectedFaceSet*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSubContractResource>(const DB& db, const LIST& params, IfcSubContractResource* in) +template <> size_t GenericFill<IfcDuctSilencerType>(const DB& db, const LIST& params, IfcDuctSilencerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTreatmentDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSweptDiskSolid>(const DB& db, const LIST& params, IfcSweptDiskSolid* in) +template <> size_t GenericFill<IfcFurnishingElementType>(const DB& db, const LIST& params, IfcFurnishingElementType* in) { - size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCompositeProfileDef>(const DB& db, const LIST& params, IfcCompositeProfileDef* in) +template <> size_t GenericFill<IfcSystemFurnitureElementType>(const DB& db, const LIST& params, IfcSystemFurnitureElementType* in) { - size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFurnishingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTankType>(const DB& db, const LIST& params, IfcTankType* in) +template <> size_t GenericFill<IfcWasteTerminalType>(const DB& db, const LIST& params, IfcWasteTerminalType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowStorageDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSphere>(const DB& db, const LIST& params, IfcSphere* in) +template <> size_t GenericFill<IfcBSplineCurve>(const DB& db, const LIST& params, IfcBSplineCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcBSplineCurve"); } do { // convert the 'Degree' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Degree, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBSplineCurve to be a `INTEGER`")); } + } while(0); + do { // convert the 'ControlPointsList' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->ControlPointsList, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBSplineCurve to be a `LIST [2:?] OF IfcCartesianPoint`")); } + } while(0); + do { // convert the 'CurveForm' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[2]=true; break; } + try { GenericConvert( in->CurveForm, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBSplineCurve to be a `IfcBSplineCurveForm`")); } + } while(0); + do { // convert the 'ClosedCurve' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[3]=true; break; } + try { GenericConvert( in->ClosedCurve, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBSplineCurve to be a `LOGICAL`")); } + } while(0); + do { // convert the 'SelfIntersect' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBSplineCurve,5>::aux_is_derived[4]=true; break; } + try { GenericConvert( in->SelfIntersect, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcBSplineCurve to be a `LOGICAL`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPolyLoop>(const DB& db, const LIST& params, IfcPolyLoop* in) +template <> size_t GenericFill<IfcBezierCurve>(const DB& db, const LIST& params, IfcBezierCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyLoop"); } do { // convert the 'Polygon' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Polygon, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyLoop to be a `LIST [3:?] OF IfcCartesianPoint`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcBSplineCurve*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCableCarrierFittingType>(const DB& db, const LIST& params, IfcCableCarrierFittingType* in) +template <> size_t GenericFill<IfcActuatorType>(const DB& db, const LIST& params, IfcActuatorType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcHumidifierType>(const DB& db, const LIST& params, IfcHumidifierType* in) +template <> size_t GenericFill<IfcDistributionControlElement>(const DB& db, const LIST& params, IfcDistributionControlElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPerformanceHistory>(const DB& db, const LIST& params, IfcPerformanceHistory* in) +template <> size_t GenericFill<IfcAnnotation>(const DB& db, const LIST& params, IfcAnnotation* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); + if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcAnnotation"); } return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcShellBasedSurfaceModel>(const DB& db, const LIST& params, IfcShellBasedSurfaceModel* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcShellBasedSurfaceModel"); } do { // convert the 'SbsmBoundary' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->SbsmBoundary, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcShellBasedSurfaceModel to be a `SET [1:?] OF IfcShell`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcActionRequest>(const DB& db, const LIST& params, IfcActionRequest* in) { size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcShapeModel>(const DB& db, const LIST& params, IfcShapeModel* in) +template <> size_t GenericFill<IfcExtrudedAreaSolid>(const DB& db, const LIST& params, IfcExtrudedAreaSolid* in) { - size_t base = GenericFill(db,params,static_cast<IfcRepresentation*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcExtrudedAreaSolid"); } do { // convert the 'ExtrudedDirection' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->ExtrudedDirection, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcExtrudedAreaSolid to be a `IfcDirection`")); } + } while(0); + do { // convert the 'Depth' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Depth, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcExtrudedAreaSolid to be a `IfcPositiveLengthMeasure`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcSystem>(const DB& db, const LIST& params, IfcSystem* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTopologyRepresentation>(const DB& db, const LIST& params, IfcTopologyRepresentation* in) +template <> size_t GenericFill<IfcFillAreaStyleHatching>(const DB& db, const LIST& params, IfcFillAreaStyleHatching* in) { - size_t base = GenericFill(db,params,static_cast<IfcShapeModel*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBuilding>(const DB& db, const LIST& params, IfcBuilding* in) +template <> size_t GenericFill<IfcRelVoidsElement>(const DB& db, const LIST& params, IfcRelVoidsElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in)); - if (params.GetSize() < 12) { throw STEP::TypeError("expected 12 arguments to IfcBuilding"); } do { // convert the 'ElevationOfRefHeight' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ElevationOfRefHeight, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcBuilding to be a `IfcLengthMeasure`")); } - } while(0); - do { // convert the 'ElevationOfTerrain' argument + size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in)); + if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelVoidsElement"); } do { // convert the 'RelatingBuildingElement' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->ElevationOfTerrain, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcBuilding to be a `IfcLengthMeasure`")); } + try { GenericConvert( in->RelatingBuildingElement, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelVoidsElement to be a `IfcElement`")); } } while(0); - do { // convert the 'BuildingAddress' argument + do { // convert the 'RelatedOpeningElement' argument boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->BuildingAddress, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 11 to IfcBuilding to be a `IfcPostalAddress`")); } + try { GenericConvert( in->RelatedOpeningElement, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelVoidsElement to be a `IfcFeatureElementSubtraction`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRoundedRectangleProfileDef>(const DB& db, const LIST& params, IfcRoundedRectangleProfileDef* in) +template <> size_t GenericFill<IfcSurfaceCurveSweptAreaSolid>(const DB& db, const LIST& params, IfcSurfaceCurveSweptAreaSolid* in) { - size_t base = GenericFill(db,params,static_cast<IfcRectangleProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStairFlight>(const DB& db, const LIST& params, IfcStairFlight* in) +template <> size_t GenericFill<IfcCartesianTransformationOperator3DnonUniform>(const DB& db, const LIST& params, IfcCartesianTransformationOperator3DnonUniform* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator3D*>(in)); + if (params.GetSize() < 7) { throw STEP::TypeError("expected 7 arguments to IfcCartesianTransformationOperator3DnonUniform"); } do { // convert the 'Scale2' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Scale2, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); } + } while(0); + do { // convert the 'Scale3' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Scale3, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcCartesianTransformationOperator3DnonUniform to be a `REAL`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionChamberElement>(const DB& db, const LIST& params, IfcDistributionChamberElement* in) +template <> size_t GenericFill<IfcCurtainWallType>(const DB& db, const LIST& params, IfcCurtainWallType* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcShapeRepresentation>(const DB& db, const LIST& params, IfcShapeRepresentation* in) +template <> size_t GenericFill<IfcEquipmentStandard>(const DB& db, const LIST& params, IfcEquipmentStandard* in) { - size_t base = GenericFill(db,params,static_cast<IfcShapeModel*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRampFlight>(const DB& db, const LIST& params, IfcRampFlight* in) +template <> size_t GenericFill<IfcFlowStorageDeviceType>(const DB& db, const LIST& params, IfcFlowStorageDeviceType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBeamType>(const DB& db, const LIST& params, IfcBeamType* in) +template <> size_t GenericFill<IfcDiameterDimension>(const DB& db, const LIST& params, IfcDiameterDimension* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRelDecomposes>(const DB& db, const LIST& params, IfcRelDecomposes* in) +template <> size_t GenericFill<IfcSwitchingDeviceType>(const DB& db, const LIST& params, IfcSwitchingDeviceType* in) { - size_t base = GenericFill(db,params,static_cast<IfcRelationship*>(in)); - if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelDecomposes"); } do { // convert the 'RelatingObject' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDecomposes,2>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->RelatingObject, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelDecomposes to be a `IfcObjectDefinition`")); } - } while(0); - do { // convert the 'RelatedObjects' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRelDecomposes,2>::aux_is_derived[1]=true; break; } - try { GenericConvert( in->RelatedObjects, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelDecomposes to be a `SET [1:?] OF IfcObjectDefinition`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRoof>(const DB& db, const LIST& params, IfcRoof* in) +template <> size_t GenericFill<IfcWindow>(const DB& db, const LIST& params, IfcWindow* in) { size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFooting>(const DB& db, const LIST& params, IfcFooting* in) +template <> size_t GenericFill<IfcFlowTreatmentDevice>(const DB& db, const LIST& params, IfcFlowTreatmentDevice* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLightSourceAmbient>(const DB& db, const LIST& params, IfcLightSourceAmbient* in) +template <> size_t GenericFill<IfcChillerType>(const DB& db, const LIST& params, IfcChillerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWindowStyle>(const DB& db, const LIST& params, IfcWindowStyle* in) +template <> size_t GenericFill<IfcRectangleHollowProfileDef>(const DB& db, const LIST& params, IfcRectangleHollowProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcTypeProduct*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcRectangleProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBuildingElementProxyType>(const DB& db, const LIST& params, IfcBuildingElementProxyType* in) +template <> size_t GenericFill<IfcBoxedHalfSpace>(const DB& db, const LIST& params, IfcBoxedHalfSpace* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcHalfSpaceSolid*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAxis2Placement3D>(const DB& db, const LIST& params, IfcAxis2Placement3D* in) +template <> size_t GenericFill<IfcAxis2Placement2D>(const DB& db, const LIST& params, IfcAxis2Placement2D* in) { size_t base = GenericFill(db,params,static_cast<IfcPlacement*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcAxis2Placement3D"); } do { // convert the 'Axis' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Axis, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement3D to be a `IfcDirection`")); } - } while(0); - do { // convert the 'RefDirection' argument + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis2Placement2D"); } do { // convert the 'RefDirection' argument boost::shared_ptr<const DataType> arg = params[base++]; if (dynamic_cast<const UNSET*>(&*arg)) break; try { GenericConvert( in->RefDirection, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcAxis2Placement3D to be a `IfcDirection`")); } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis2Placement2D to be a `IfcDirection`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEdgeCurve>(const DB& db, const LIST& params, IfcEdgeCurve* in) +template <> size_t GenericFill<IfcSpaceProgram>(const DB& db, const LIST& params, IfcSpaceProgram* in) { - size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcClosedShell>(const DB& db, const LIST& params, IfcClosedShell* in) +template <> size_t GenericFill<IfcPoint>(const DB& db, const LIST& params, IfcPoint* in) { - size_t base = GenericFill(db,params,static_cast<IfcConnectedFaceSet*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcClosedShell"); } return base; + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTendonAnchor>(const DB& db, const LIST& params, IfcTendonAnchor* in) +template <> size_t GenericFill<IfcCartesianPoint>(const DB& db, const LIST& params, IfcCartesianPoint* in) { - size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcCartesianPoint"); } do { // convert the 'Coordinates' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Coordinates, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianPoint to be a `LIST [1:3] OF IfcLengthMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCondenserType>(const DB& db, const LIST& params, IfcCondenserType* in) +template <> size_t GenericFill<IfcBoundedSurface>(const DB& db, const LIST& params, IfcBoundedSurface* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSurface*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPipeSegmentType>(const DB& db, const LIST& params, IfcPipeSegmentType* in) +template <> size_t GenericFill<IfcLoop>(const DB& db, const LIST& params, IfcLoop* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPointOnSurface>(const DB& db, const LIST& params, IfcPointOnSurface* in) +template <> size_t GenericFill<IfcPolyLoop>(const DB& db, const LIST& params, IfcPolyLoop* in) { - size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyLoop"); } do { // convert the 'Polygon' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Polygon, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyLoop to be a `LIST [3:?] OF IfcCartesianPoint`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAsset>(const DB& db, const LIST& params, IfcAsset* in) +template <> size_t GenericFill<IfcTerminatorSymbol>(const DB& db, const LIST& params, IfcTerminatorSymbol* in) { - size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcAnnotationSymbolOccurrence*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLightSourcePositional>(const DB& db, const LIST& params, IfcLightSourcePositional* in) +template <> size_t GenericFill<IfcDimensionCurveTerminator>(const DB& db, const LIST& params, IfcDimensionCurveTerminator* in) { - size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcTerminatorSymbol*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProjectionCurve>(const DB& db, const LIST& params, IfcProjectionCurve* in) +template <> size_t GenericFill<IfcTrapeziumProfileDef>(const DB& db, const LIST& params, IfcTrapeziumProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcAnnotationCurveOccurrence*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFillAreaStyleTiles>(const DB& db, const LIST& params, IfcFillAreaStyleTiles* in) +template <> size_t GenericFill<IfcRepresentationContext>(const DB& db, const LIST& params, IfcRepresentationContext* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = 0; + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationContext"); } do { // convert the 'ContextIdentifier' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentationContext,2>::aux_is_derived[0]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ContextIdentifier, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationContext to be a `IfcLabel`")); } + } while(0); + do { // convert the 'ContextType' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRepresentationContext,2>::aux_is_derived[1]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ContextType, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationContext to be a `IfcLabel`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcGeometricRepresentationContext>(const DB& db, const LIST& params, IfcGeometricRepresentationContext* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcRepresentationContext*>(in)); + if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcGeometricRepresentationContext"); } do { // convert the 'CoordinateSpaceDimension' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->CoordinateSpaceDimension, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcGeometricRepresentationContext to be a `IfcDimensionCount`")); } + } while(0); + do { // convert the 'Precision' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[1]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Precision, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcGeometricRepresentationContext to be a `REAL`")); } + } while(0); + do { // convert the 'WorldCoordinateSystem' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[2]=true; break; } + try { GenericConvert( in->WorldCoordinateSystem, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcGeometricRepresentationContext to be a `IfcAxis2Placement`")); } + } while(0); + do { // convert the 'TrueNorth' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcGeometricRepresentationContext,4>::aux_is_derived[3]=true; break; } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->TrueNorth, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcGeometricRepresentationContext to be a `IfcDirection`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcCurveBoundedPlane>(const DB& db, const LIST& params, IfcCurveBoundedPlane* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcBoundedSurface*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRelFillsElement>(const DB& db, const LIST& params, IfcRelFillsElement* in) +template <> size_t GenericFill<IfcSIUnit>(const DB& db, const LIST& params, IfcSIUnit* in) { - size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in)); - if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelFillsElement"); } do { // convert the 'RelatingOpeningElement' argument + size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcSIUnit"); } do { // convert the 'Prefix' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->RelatingOpeningElement, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelFillsElement to be a `IfcOpeningElement`")); } + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Prefix, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSIUnit to be a `IfcSIPrefix`")); } } while(0); - do { // convert the 'RelatedBuildingElement' argument + do { // convert the 'Name' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->RelatedBuildingElement, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelFillsElement to be a `IfcElement`")); } + try { GenericConvert( in->Name, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSIUnit to be a `IfcSIUnitName`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricMotorType>(const DB& db, const LIST& params, IfcElectricMotorType* in) +template <> size_t GenericFill<IfcStructuralReaction>(const DB& db, const LIST& params, IfcStructuralReaction* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralActivity*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTendon>(const DB& db, const LIST& params, IfcTendon* in) +template <> size_t GenericFill<IfcStructuralPointReaction>(const DB& db, const LIST& params, IfcStructuralPointReaction* in) { - size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralReaction*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionChamberElementType>(const DB& db, const LIST& params, IfcDistributionChamberElementType* in) +template <> size_t GenericFill<IfcAxis1Placement>(const DB& db, const LIST& params, IfcAxis1Placement* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcPlacement*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis1Placement"); } do { // convert the 'Axis' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Axis, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis1Placement to be a `IfcDirection`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcElectricApplianceType>(const DB& db, const LIST& params, IfcElectricApplianceType* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMemberType>(const DB& db, const LIST& params, IfcMemberType* in) +template <> size_t GenericFill<IfcSensorType>(const DB& db, const LIST& params, IfcSensorType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralLinearAction>(const DB& db, const LIST& params, IfcStructuralLinearAction* in) +template <> size_t GenericFill<IfcFurnishingElement>(const DB& db, const LIST& params, IfcFurnishingElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralLinearActionVarying>(const DB& db, const LIST& params, IfcStructuralLinearActionVarying* in) +template <> size_t GenericFill<IfcProtectiveDeviceType>(const DB& db, const LIST& params, IfcProtectiveDeviceType* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralLinearAction*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProductDefinitionShape>(const DB& db, const LIST& params, IfcProductDefinitionShape* in) +template <> size_t GenericFill<IfcZShapeProfileDef>(const DB& db, const LIST& params, IfcZShapeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcProductRepresentation*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFastener>(const DB& db, const LIST& params, IfcFastener* in) +template <> size_t GenericFill<IfcScheduleTimeControl>(const DB& db, const LIST& params, IfcScheduleTimeControl* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementComponent*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMechanicalFastener>(const DB& db, const LIST& params, IfcMechanicalFastener* in) +template <> size_t GenericFill<IfcRepresentationMap>(const DB& db, const LIST& params, IfcRepresentationMap* in) { - size_t base = GenericFill(db,params,static_cast<IfcFastener*>(in)); + size_t base = 0; + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationMap"); } do { // convert the 'MappingOrigin' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->MappingOrigin, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationMap to be a `IfcAxis2Placement`")); } + } while(0); + do { // convert the 'MappedRepresentation' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->MappedRepresentation, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationMap to be a `IfcRepresentation`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcClosedShell>(const DB& db, const LIST& params, IfcClosedShell* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcConnectedFaceSet*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcClosedShell"); } return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcBuildingElementPart>(const DB& db, const LIST& params, IfcBuildingElementPart* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementComponent*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEvaporatorType>(const DB& db, const LIST& params, IfcEvaporatorType* in) +template <> size_t GenericFill<IfcBlock>(const DB& db, const LIST& params, IfcBlock* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDiscreteAccessoryType>(const DB& db, const LIST& params, IfcDiscreteAccessoryType* in) +template <> size_t GenericFill<IfcLightFixtureType>(const DB& db, const LIST& params, IfcLightFixtureType* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementComponentType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralCurveConnection>(const DB& db, const LIST& params, IfcStructuralCurveConnection* in) +template <> size_t GenericFill<IfcOpeningElement>(const DB& db, const LIST& params, IfcOpeningElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcStructuralConnection*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFeatureElementSubtraction*>(in)); + if (params.GetSize() < 8) { throw STEP::TypeError("expected 8 arguments to IfcOpeningElement"); } return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcLightSourceSpot>(const DB& db, const LIST& params, IfcLightSourceSpot* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcLightSourcePositional*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProjectionElement>(const DB& db, const LIST& params, IfcProjectionElement* in) +template <> size_t GenericFill<IfcTendonAnchor>(const DB& db, const LIST& params, IfcTendonAnchor* in) { - size_t base = GenericFill(db,params,static_cast<IfcFeatureElementAddition*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCoveringType>(const DB& db, const LIST& params, IfcCoveringType* in) +template <> size_t GenericFill<IfcElectricFlowStorageDeviceType>(const DB& db, const LIST& params, IfcElectricFlowStorageDeviceType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowStorageDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPumpType>(const DB& db, const LIST& params, IfcPumpType* in) +template <> size_t GenericFill<IfcSphere>(const DB& db, const LIST& params, IfcSphere* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPile>(const DB& db, const LIST& params, IfcPile* in) +template <> size_t GenericFill<IfcDamperType>(const DB& db, const LIST& params, IfcDamperType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcUnitAssignment>(const DB& db, const LIST& params, IfcUnitAssignment* in) +template <> size_t GenericFill<IfcProjectOrderRecord>(const DB& db, const LIST& params, IfcProjectOrderRecord* in) { - size_t base = 0; - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcUnitAssignment"); } do { // convert the 'Units' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Units, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcUnitAssignment to be a `SET [1:?] OF IfcUnit`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBoundingBox>(const DB& db, const LIST& params, IfcBoundingBox* in) +template <> size_t GenericFill<IfcDistributionChamberElement>(const DB& db, const LIST& params, IfcDistributionChamberElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcBoundingBox"); } do { // convert the 'Corner' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Corner, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBoundingBox to be a `IfcCartesianPoint`")); } - } while(0); - do { // convert the 'XDim' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->XDim, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); } - } while(0); - do { // convert the 'YDim' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->YDim, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); } - } while(0); - do { // convert the 'ZDim' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->ZDim, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcShellBasedSurfaceModel>(const DB& db, const LIST& params, IfcShellBasedSurfaceModel* in) +template <> size_t GenericFill<IfcMechanicalFastener>(const DB& db, const LIST& params, IfcMechanicalFastener* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcShellBasedSurfaceModel"); } do { // convert the 'SbsmBoundary' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->SbsmBoundary, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcShellBasedSurfaceModel to be a `SET [1:?] OF IfcShell`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcFastener*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFacetedBrep>(const DB& db, const LIST& params, IfcFacetedBrep* in) +template <> size_t GenericFill<IfcRectangularTrimmedSurface>(const DB& db, const LIST& params, IfcRectangularTrimmedSurface* in) { - size_t base = GenericFill(db,params,static_cast<IfcManifoldSolidBrep*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBoundedSurface*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTextLiteralWithExtent>(const DB& db, const LIST& params, IfcTextLiteralWithExtent* in) +template <> size_t GenericFill<IfcZone>(const DB& db, const LIST& params, IfcZone* in) { - size_t base = GenericFill(db,params,static_cast<IfcTextLiteral*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricApplianceType>(const DB& db, const LIST& params, IfcElectricApplianceType* in) +template <> size_t GenericFill<IfcFanType>(const DB& db, const LIST& params, IfcFanType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTrapeziumProfileDef>(const DB& db, const LIST& params, IfcTrapeziumProfileDef* in) +template <> size_t GenericFill<IfcGeometricSet>(const DB& db, const LIST& params, IfcGeometricSet* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRelContainedInSpatialStructure>(const DB& db, const LIST& params, IfcRelContainedInSpatialStructure* in) +template <> size_t GenericFill<IfcFillAreaStyleTiles>(const DB& db, const LIST& params, IfcFillAreaStyleTiles* in) { - size_t base = GenericFill(db,params,static_cast<IfcRelConnects*>(in)); - if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelContainedInSpatialStructure"); } do { // convert the 'RelatedElements' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->RelatedElements, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcRelContainedInSpatialStructure to be a `SET [1:?] OF IfcProduct`")); } - } while(0); - do { // convert the 'RelatingStructure' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->RelatingStructure, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcRelContainedInSpatialStructure to be a `IfcSpatialStructureElement`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEdgeLoop>(const DB& db, const LIST& params, IfcEdgeLoop* in) +template <> size_t GenericFill<IfcCableSegmentType>(const DB& db, const LIST& params, IfcCableSegmentType* in) { - size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProject>(const DB& db, const LIST& params, IfcProject* in) +template <> size_t GenericFill<IfcRelOverridesProperties>(const DB& db, const LIST& params, IfcRelOverridesProperties* in) { - size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); - if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcProject"); } do { // convert the 'LongName' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->LongName, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcProject to be a `IfcLabel`")); } - } while(0); - do { // convert the 'Phase' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Phase, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcProject to be a `IfcLabel`")); } - } while(0); - do { // convert the 'RepresentationContexts' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->RepresentationContexts, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcProject to be a `SET [1:?] OF IfcRepresentationContext`")); } - } while(0); - do { // convert the 'UnitsInContext' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->UnitsInContext, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcProject to be a `IfcUnitAssignment`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcRelDefinesByProperties*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCartesianPoint>(const DB& db, const LIST& params, IfcCartesianPoint* in) +template <> size_t GenericFill<IfcMeasureWithUnit>(const DB& db, const LIST& params, IfcMeasureWithUnit* in) { - size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcCartesianPoint"); } do { // convert the 'Coordinates' argument + size_t base = 0; + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMeasureWithUnit"); } do { // convert the 'ValueComponent' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Coordinates, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCartesianPoint to be a `LIST [1:3] OF IfcLengthMeasure`")); } + try { GenericConvert( in->ValueComponent, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMeasureWithUnit to be a `IfcValue`")); } + } while(0); + do { // convert the 'UnitComponent' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->UnitComponent, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMeasureWithUnit to be a `IfcUnit`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCurveBoundedPlane>(const DB& db, const LIST& params, IfcCurveBoundedPlane* in) +template <> size_t GenericFill<IfcSlabType>(const DB& db, const LIST& params, IfcSlabType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBoundedSurface*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWallType>(const DB& db, const LIST& params, IfcWallType* in) +template <> size_t GenericFill<IfcServiceLife>(const DB& db, const LIST& params, IfcServiceLife* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFillAreaStyleHatching>(const DB& db, const LIST& params, IfcFillAreaStyleHatching* in) +template <> size_t GenericFill<IfcFurnitureType>(const DB& db, const LIST& params, IfcFurnitureType* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFurnishingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEquipmentStandard>(const DB& db, const LIST& params, IfcEquipmentStandard* in) +template <> size_t GenericFill<IfcCostItem>(const DB& db, const LIST& params, IfcCostItem* in) { size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDiameterDimension>(const DB& db, const LIST& params, IfcDiameterDimension* in) +template <> size_t GenericFill<IfcReinforcingMesh>(const DB& db, const LIST& params, IfcReinforcingMesh* in) { - size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralLoadGroup>(const DB& db, const LIST& params, IfcStructuralLoadGroup* in) +template <> size_t GenericFill<IfcFacetedBrepWithVoids>(const DB& db, const LIST& params, IfcFacetedBrepWithVoids* in) { - size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcManifoldSolidBrep*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcConstructionMaterialResource>(const DB& db, const LIST& params, IfcConstructionMaterialResource* in) +template <> size_t GenericFill<IfcGasTerminalType>(const DB& db, const LIST& params, IfcGasTerminalType* in) { - size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRelAggregates>(const DB& db, const LIST& params, IfcRelAggregates* in) +template <> size_t GenericFill<IfcPile>(const DB& db, const LIST& params, IfcPile* in) { - size_t base = GenericFill(db,params,static_cast<IfcRelDecomposes*>(in)); - if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelAggregates"); } return base; + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members + return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBoilerType>(const DB& db, const LIST& params, IfcBoilerType* in) +template <> size_t GenericFill<IfcFillAreaStyleTileSymbolWithStyle>(const DB& db, const LIST& params, IfcFillAreaStyleTileSymbolWithStyle* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcColourSpecification>(const DB& db, const LIST& params, IfcColourSpecification* in) +template <> size_t GenericFill<IfcConstructionMaterialResource>(const DB& db, const LIST& params, IfcConstructionMaterialResource* in) { - size_t base = 0; - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcColourSpecification"); } do { // convert the 'Name' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcColourSpecification,1>::aux_is_derived[0]=true; break; } - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->Name, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcColourSpecification to be a `IfcLabel`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcColourRgb>(const DB& db, const LIST& params, IfcColourRgb* in) +template <> size_t GenericFill<IfcAnnotationCurveOccurrence>(const DB& db, const LIST& params, IfcAnnotationCurveOccurrence* in) { - size_t base = GenericFill(db,params,static_cast<IfcColourSpecification*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcColourRgb"); } do { // convert the 'Red' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Red, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); } - } while(0); - do { // convert the 'Green' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Green, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); } - } while(0); - do { // convert the 'Blue' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Blue, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcColourRgb to be a `IfcNormalisedRatioMeasure`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDoorStyle>(const DB& db, const LIST& params, IfcDoorStyle* in) +template <> size_t GenericFill<IfcDimensionCurve>(const DB& db, const LIST& params, IfcDimensionCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcTypeProduct*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcAnnotationCurveOccurrence*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDuctSilencerType>(const DB& db, const LIST& params, IfcDuctSilencerType* in) +template <> size_t GenericFill<IfcGeometricCurveSet>(const DB& db, const LIST& params, IfcGeometricCurveSet* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTreatmentDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricSet*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLightSourceGoniometric>(const DB& db, const LIST& params, IfcLightSourceGoniometric* in) +template <> size_t GenericFill<IfcRelAggregates>(const DB& db, const LIST& params, IfcRelAggregates* in) { - size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcRelDecomposes*>(in)); + if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcRelAggregates"); } return base; +} +// ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill<IfcFaceBasedSurfaceModel>(const DB& db, const LIST& params, IfcFaceBasedSurfaceModel* in) +{ + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFaceBasedSurfaceModel"); } do { // convert the 'FbsmFaces' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->FbsmFaces, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBasedSurfaceModel to be a `SET [1:?] OF IfcConnectedFaceSet`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcActuatorType>(const DB& db, const LIST& params, IfcActuatorType* in) +template <> size_t GenericFill<IfcEnergyConversionDevice>(const DB& db, const LIST& params, IfcEnergyConversionDevice* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSensorType>(const DB& db, const LIST& params, IfcSensorType* in) +template <> size_t GenericFill<IfcRampFlight>(const DB& db, const LIST& params, IfcRampFlight* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAirTerminalBoxType>(const DB& db, const LIST& params, IfcAirTerminalBoxType* in) +template <> size_t GenericFill<IfcVertexLoop>(const DB& db, const LIST& params, IfcVertexLoop* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotationSurfaceOccurrence>(const DB& db, const LIST& params, IfcAnnotationSurfaceOccurrence* in) +template <> size_t GenericFill<IfcPlate>(const DB& db, const LIST& params, IfcPlate* in) { - size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcZShapeProfileDef>(const DB& db, const LIST& params, IfcZShapeProfileDef* in) +template <> size_t GenericFill<IfcUShapeProfileDef>(const DB& db, const LIST& params, IfcUShapeProfileDef* in) { size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRationalBezierCurve>(const DB& db, const LIST& params, IfcRationalBezierCurve* in) +template <> size_t GenericFill<IfcFaceBound>(const DB& db, const LIST& params, IfcFaceBound* in) { - size_t base = GenericFill(db,params,static_cast<IfcBezierCurve*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcFaceBound"); } do { // convert the 'Bound' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFaceBound,2>::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Bound, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBound to be a `IfcLoop`")); } + } while(0); + do { // convert the 'Orientation' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcFaceBound,2>::aux_is_derived[1]=true; break; } + try { GenericConvert( in->Orientation, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcFaceBound to be a `BOOLEAN`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCartesianTransformationOperator2D>(const DB& db, const LIST& params, IfcCartesianTransformationOperator2D* in) +template <> size_t GenericFill<IfcFaceOuterBound>(const DB& db, const LIST& params, IfcFaceOuterBound* in) { - size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members - return base; + size_t base = GenericFill(db,params,static_cast<IfcFaceBound*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcFaceOuterBound"); } return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCartesianTransformationOperator2DnonUniform>(const DB& db, const LIST& params, IfcCartesianTransformationOperator2DnonUniform* in) +template <> size_t GenericFill<IfcOneDirectionRepeatFactor>(const DB& db, const LIST& params, IfcOneDirectionRepeatFactor* in) { - size_t base = GenericFill(db,params,static_cast<IfcCartesianTransformationOperator2D*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMove>(const DB& db, const LIST& params, IfcMove* in) +template <> size_t GenericFill<IfcBoilerType>(const DB& db, const LIST& params, IfcBoilerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcTask*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCableCarrierSegmentType>(const DB& db, const LIST& params, IfcCableCarrierSegmentType* in) +template <> size_t GenericFill<IfcConstructionEquipmentResource>(const DB& db, const LIST& params, IfcConstructionEquipmentResource* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricalElement>(const DB& db, const LIST& params, IfcElectricalElement* in) +template <> size_t GenericFill<IfcComplexProperty>(const DB& db, const LIST& params, IfcComplexProperty* in) { - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcProperty*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcComplexProperty"); } do { // convert the 'UsageName' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->UsageName, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcComplexProperty to be a `IfcIdentifier`")); } + } while(0); + do { // convert the 'HasProperties' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->HasProperties, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcComplexProperty to be a `SET [1:?] OF IfcProperty`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcChillerType>(const DB& db, const LIST& params, IfcChillerType* in) +template <> size_t GenericFill<IfcFooting>(const DB& db, const LIST& params, IfcFooting* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcReinforcingBar>(const DB& db, const LIST& params, IfcReinforcingBar* in) +template <> size_t GenericFill<IfcConstructionProductResource>(const DB& db, const LIST& params, IfcConstructionProductResource* in) { - size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcConstructionResource*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCShapeProfileDef>(const DB& db, const LIST& params, IfcCShapeProfileDef* in) +template <> size_t GenericFill<IfcDerivedProfileDef>(const DB& db, const LIST& params, IfcDerivedProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPermit>(const DB& db, const LIST& params, IfcPermit* in) +template <> size_t GenericFill<IfcPropertyTableValue>(const DB& db, const LIST& params, IfcPropertyTableValue* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSimpleProperty*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSlabType>(const DB& db, const LIST& params, IfcSlabType* in) +template <> size_t GenericFill<IfcFlowMeterType>(const DB& db, const LIST& params, IfcFlowMeterType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLampType>(const DB& db, const LIST& params, IfcLampType* in) +template <> size_t GenericFill<IfcDoorStyle>(const DB& db, const LIST& params, IfcDoorStyle* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcTypeProduct*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPlanarExtent>(const DB& db, const LIST& params, IfcPlanarExtent* in) +template <> size_t GenericFill<IfcUnitAssignment>(const DB& db, const LIST& params, IfcUnitAssignment* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = 0; + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcUnitAssignment"); } do { // convert the 'Units' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Units, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcUnitAssignment to be a `SET [1:?] OF IfcUnit`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAlarmType>(const DB& db, const LIST& params, IfcAlarmType* in) +template <> size_t GenericFill<IfcFlowTerminal>(const DB& db, const LIST& params, IfcFlowTerminal* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricFlowStorageDeviceType>(const DB& db, const LIST& params, IfcElectricFlowStorageDeviceType* in) +template <> size_t GenericFill<IfcCraneRailFShapeProfileDef>(const DB& db, const LIST& params, IfcCraneRailFShapeProfileDef* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowStorageDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEquipmentElement>(const DB& db, const LIST& params, IfcEquipmentElement* in) +template <> size_t GenericFill<IfcFlowSegment>(const DB& db, const LIST& params, IfcFlowSegment* in) { - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLightFixtureType>(const DB& db, const LIST& params, IfcLightFixtureType* in) +template <> size_t GenericFill<IfcElementQuantity>(const DB& db, const LIST& params, IfcElementQuantity* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcPropertySetDefinition*>(in)); + if (params.GetSize() < 6) { throw STEP::TypeError("expected 6 arguments to IfcElementQuantity"); } do { // convert the 'MethodOfMeasurement' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->MethodOfMeasurement, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcElementQuantity to be a `IfcLabel`")); } + } while(0); + do { // convert the 'Quantities' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Quantities, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcElementQuantity to be a `SET [1:?] OF IfcPhysicalQuantity`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- @@ -4196,601 +4432,595 @@ template <> size_t GenericFill<IfcCurtainWall>(const DB& db, const LIST& params, return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSlab>(const DB& db, const LIST& params, IfcSlab* in) +template <> size_t GenericFill<IfcDiscreteAccessory>(const DB& db, const LIST& params, IfcDiscreteAccessory* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElementComponent*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCurtainWallType>(const DB& db, const LIST& params, IfcCurtainWallType* in) +template <> size_t GenericFill<IfcGrid>(const DB& db, const LIST& params, IfcGrid* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOutletType>(const DB& db, const LIST& params, IfcOutletType* in) +template <> size_t GenericFill<IfcSanitaryTerminalType>(const DB& db, const LIST& params, IfcSanitaryTerminalType* in) { size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCompressorType>(const DB& db, const LIST& params, IfcCompressorType* in) +template <> size_t GenericFill<IfcSubedge>(const DB& db, const LIST& params, IfcSubedge* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowMovingDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCraneRailAShapeProfileDef>(const DB& db, const LIST& params, IfcCraneRailAShapeProfileDef* in) +template <> size_t GenericFill<IfcFilterType>(const DB& db, const LIST& params, IfcFilterType* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowTreatmentDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowSegment>(const DB& db, const LIST& params, IfcFlowSegment* in) +template <> size_t GenericFill<IfcTendon>(const DB& db, const LIST& params, IfcTendon* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcReinforcingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSectionedSpine>(const DB& db, const LIST& params, IfcSectionedSpine* in) +template <> size_t GenericFill<IfcStructuralLoadGroup>(const DB& db, const LIST& params, IfcStructuralLoadGroup* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricTimeControlType>(const DB& db, const LIST& params, IfcElectricTimeControlType* in) +template <> size_t GenericFill<IfcPresentationStyleAssignment>(const DB& db, const LIST& params, IfcPresentationStyleAssignment* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = 0; + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyleAssignment"); } do { // convert the 'Styles' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Styles, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPresentationStyleAssignment to be a `SET [1:?] OF IfcPresentationStyleSelect`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFaceSurface>(const DB& db, const LIST& params, IfcFaceSurface* in) +template <> size_t GenericFill<IfcStructuralCurveMember>(const DB& db, const LIST& params, IfcStructuralCurveMember* in) { - size_t base = GenericFill(db,params,static_cast<IfcFace*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralMember*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMotorConnectionType>(const DB& db, const LIST& params, IfcMotorConnectionType* in) +template <> size_t GenericFill<IfcLightSourceAmbient>(const DB& db, const LIST& params, IfcLightSourceAmbient* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcLightSource*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowFitting>(const DB& db, const LIST& params, IfcFlowFitting* in) +template <> size_t GenericFill<IfcCondition>(const DB& db, const LIST& params, IfcCondition* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPointOnCurve>(const DB& db, const LIST& params, IfcPointOnCurve* in) +template <> size_t GenericFill<IfcPort>(const DB& db, const LIST& params, IfcPort* in) { - size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProduct*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTransportElementType>(const DB& db, const LIST& params, IfcTransportElementType* in) +template <> size_t GenericFill<IfcSpace>(const DB& db, const LIST& params, IfcSpace* in) { - size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcSpatialStructureElement*>(in)); + if (params.GetSize() < 11) { throw STEP::TypeError("expected 11 arguments to IfcSpace"); } do { // convert the 'InteriorOrExteriorSpace' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->InteriorOrExteriorSpace, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcSpace to be a `IfcInternalOrExternalEnum`")); } + } while(0); + do { // convert the 'ElevationWithFlooring' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ElevationWithFlooring, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 10 to IfcSpace to be a `IfcLengthMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCableSegmentType>(const DB& db, const LIST& params, IfcCableSegmentType* in) +template <> size_t GenericFill<IfcHeatExchangerType>(const DB& db, const LIST& params, IfcHeatExchangerType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotationSurface>(const DB& db, const LIST& params, IfcAnnotationSurface* in) +template <> size_t GenericFill<IfcTankType>(const DB& db, const LIST& params, IfcTankType* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowStorageDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCompositeCurveSegment>(const DB& db, const LIST& params, IfcCompositeCurveSegment* in) +template <> size_t GenericFill<IfcInventory>(const DB& db, const LIST& params, IfcInventory* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcCompositeCurveSegment"); } do { // convert the 'Transition' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Transition, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcCompositeCurveSegment to be a `IfcTransitionCode`")); } - } while(0); - do { // convert the 'SameSense' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->SameSense, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCompositeCurveSegment to be a `BOOLEAN`")); } - } while(0); - do { // convert the 'ParentCurve' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->ParentCurve, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcCompositeCurveSegment to be a `IfcCurve`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcServiceLife>(const DB& db, const LIST& params, IfcServiceLife* in) +template <> size_t GenericFill<IfcTransportElementType>(const DB& db, const LIST& params, IfcTransportElementType* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPlateType>(const DB& db, const LIST& params, IfcPlateType* in) +template <> size_t GenericFill<IfcAirToAirHeatRecoveryType>(const DB& db, const LIST& params, IfcAirToAirHeatRecoveryType* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcVibrationIsolatorType>(const DB& db, const LIST& params, IfcVibrationIsolatorType* in) +template <> size_t GenericFill<IfcStairFlight>(const DB& db, const LIST& params, IfcStairFlight* in) { - size_t base = GenericFill(db,params,static_cast<IfcDiscreteAccessoryType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTrimmedCurve>(const DB& db, const LIST& params, IfcTrimmedCurve* in) +template <> size_t GenericFill<IfcElectricalElement>(const DB& db, const LIST& params, IfcElectricalElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in)); - if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcTrimmedCurve"); } do { // convert the 'BasisCurve' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->BasisCurve, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcTrimmedCurve to be a `IfcCurve`")); } - } while(0); - do { // convert the 'Trim1' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Trim1, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); } - } while(0); - do { // convert the 'Trim2' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Trim2, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcTrimmedCurve to be a `SET [1:2] OF IfcTrimmingSelect`")); } - } while(0); - do { // convert the 'SenseAgreement' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->SenseAgreement, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcTrimmedCurve to be a `BOOLEAN`")); } - } while(0); - do { // convert the 'MasterRepresentation' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->MasterRepresentation, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcTrimmedCurve to be a `IfcTrimmingPreference`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMappedItem>(const DB& db, const LIST& params, IfcMappedItem* in) +template <> size_t GenericFill<IfcSurfaceStyleWithTextures>(const DB& db, const LIST& params, IfcSurfaceStyleWithTextures* in) { - size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in)); - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMappedItem"); } do { // convert the 'MappingSource' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->MappingSource, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMappedItem to be a `IfcRepresentationMap`")); } - } while(0); - do { // convert the 'MappingTarget' argument + size_t base = 0; + if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleWithTextures"); } do { // convert the 'Textures' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->MappingTarget, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMappedItem to be a `IfcCartesianTransformationOperator`")); } + try { GenericConvert( in->Textures, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcSurfaceStyleWithTextures to be a `LIST [1:?] OF IfcSurfaceTexture`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDirection>(const DB& db, const LIST& params, IfcDirection* in) +template <> size_t GenericFill<IfcBoundingBox>(const DB& db, const LIST& params, IfcBoundingBox* in) { size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcDirection"); } do { // convert the 'DirectionRatios' argument + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcBoundingBox"); } do { // convert the 'Corner' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->DirectionRatios, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcDirection to be a `LIST [2:3] OF REAL`")); } + try { GenericConvert( in->Corner, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBoundingBox to be a `IfcCartesianPoint`")); } + } while(0); + do { // convert the 'XDim' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->XDim, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'YDim' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->YDim, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'ZDim' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->ZDim, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcBoundingBox to be a `IfcPositiveLengthMeasure`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBlock>(const DB& db, const LIST& params, IfcBlock* in) +template <> size_t GenericFill<IfcWallType>(const DB& db, const LIST& params, IfcWallType* in) { - size_t base = GenericFill(db,params,static_cast<IfcCsgPrimitive3D*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcProjectOrderRecord>(const DB& db, const LIST& params, IfcProjectOrderRecord* in) +template <> size_t GenericFill<IfcMove>(const DB& db, const LIST& params, IfcMove* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcTask*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowMeterType>(const DB& db, const LIST& params, IfcFlowMeterType* in) +template <> size_t GenericFill<IfcCircle>(const DB& db, const LIST& params, IfcCircle* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowControllerType*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcConic*>(in)); + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcCircle"); } do { // convert the 'Radius' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->Radius, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcCircle to be a `IfcPositiveLengthMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcControllerType>(const DB& db, const LIST& params, IfcControllerType* in) +template <> size_t GenericFill<IfcOffsetCurve2D>(const DB& db, const LIST& params, IfcOffsetCurve2D* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionControlElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBeam>(const DB& db, const LIST& params, IfcBeam* in) +template <> size_t GenericFill<IfcPointOnCurve>(const DB& db, const LIST& params, IfcPointOnCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcArbitraryOpenProfileDef>(const DB& db, const LIST& params, IfcArbitraryOpenProfileDef* in) +template <> size_t GenericFill<IfcStructuralResultGroup>(const DB& db, const LIST& params, IfcStructuralResultGroup* in) { - size_t base = GenericFill(db,params,static_cast<IfcProfileDef*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcArbitraryOpenProfileDef"); } do { // convert the 'Curve' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcArbitraryOpenProfileDef,1>::aux_is_derived[0]=true; break; } - try { GenericConvert( in->Curve, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcArbitraryOpenProfileDef to be a `IfcBoundedCurve`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCenterLineProfileDef>(const DB& db, const LIST& params, IfcCenterLineProfileDef* in) +template <> size_t GenericFill<IfcSectionedSpine>(const DB& db, const LIST& params, IfcSectionedSpine* in) { - size_t base = GenericFill(db,params,static_cast<IfcArbitraryOpenProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTimeSeriesSchedule>(const DB& db, const LIST& params, IfcTimeSeriesSchedule* in) +template <> size_t GenericFill<IfcSlab>(const DB& db, const LIST& params, IfcSlab* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRoundedEdgeFeature>(const DB& db, const LIST& params, IfcRoundedEdgeFeature* in) +template <> size_t GenericFill<IfcVertex>(const DB& db, const LIST& params, IfcVertex* in) { - size_t base = GenericFill(db,params,static_cast<IfcEdgeFeature*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcIShapeProfileDef>(const DB& db, const LIST& params, IfcIShapeProfileDef* in) +template <> size_t GenericFill<IfcVertexPoint>(const DB& db, const LIST& params, IfcVertexPoint* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcVertex*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcSpaceHeaterType>(const DB& db, const LIST& params, IfcSpaceHeaterType* in) +template <> size_t GenericFill<IfcStructuralLinearAction>(const DB& db, const LIST& params, IfcStructuralLinearAction* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFlowStorageDevice>(const DB& db, const LIST& params, IfcFlowStorageDevice* in) +template <> size_t GenericFill<IfcStructuralLinearActionVarying>(const DB& db, const LIST& params, IfcStructuralLinearActionVarying* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralLinearAction*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRevolvedAreaSolid>(const DB& db, const LIST& params, IfcRevolvedAreaSolid* in) +template <> size_t GenericFill<IfcBuildingElementProxyType>(const DB& db, const LIST& params, IfcBuildingElementProxyType* in) { - size_t base = GenericFill(db,params,static_cast<IfcSweptAreaSolid*>(in)); - if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRevolvedAreaSolid"); } do { // convert the 'Axis' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Axis, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRevolvedAreaSolid to be a `IfcAxis1Placement`")); } - } while(0); - do { // convert the 'Angle' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Angle, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRevolvedAreaSolid to be a `IfcPlaneAngleMeasure`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDoor>(const DB& db, const LIST& params, IfcDoor* in) +template <> size_t GenericFill<IfcProjectionElement>(const DB& db, const LIST& params, IfcProjectionElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElement*>(in)); - if (params.GetSize() < 10) { throw STEP::TypeError("expected 10 arguments to IfcDoor"); } do { // convert the 'OverallHeight' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->OverallHeight, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcDoor to be a `IfcPositiveLengthMeasure`")); } - } while(0); - do { // convert the 'OverallWidth' argument - boost::shared_ptr<const DataType> arg = params[base++]; - if (dynamic_cast<const UNSET*>(&*arg)) break; - try { GenericConvert( in->OverallWidth, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 9 to IfcDoor to be a `IfcPositiveLengthMeasure`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcFeatureElementAddition*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEllipse>(const DB& db, const LIST& params, IfcEllipse* in) +template <> size_t GenericFill<IfcConversionBasedUnit>(const DB& db, const LIST& params, IfcConversionBasedUnit* in) { - size_t base = GenericFill(db,params,static_cast<IfcConic*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcEllipse"); } do { // convert the 'SemiAxis1' argument + size_t base = GenericFill(db,params,static_cast<IfcNamedUnit*>(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcConversionBasedUnit"); } do { // convert the 'Name' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->SemiAxis1, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); } + try { GenericConvert( in->Name, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcConversionBasedUnit to be a `IfcLabel`")); } } while(0); - do { // convert the 'SemiAxis2' argument + do { // convert the 'ConversionFactor' argument boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->SemiAxis2, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); } + try { GenericConvert( in->ConversionFactor, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcConversionBasedUnit to be a `IfcMeasureWithUnit`")); } } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTubeBundleType>(const DB& db, const LIST& params, IfcTubeBundleType* in) +template <> size_t GenericFill<IfcGeometricRepresentationSubContext>(const DB& db, const LIST& params, IfcGeometricRepresentationSubContext* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationContext*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAngularDimension>(const DB& db, const LIST& params, IfcAngularDimension* in) +template <> size_t GenericFill<IfcAnnotationSurfaceOccurrence>(const DB& db, const LIST& params, IfcAnnotationSurfaceOccurrence* in) { - size_t base = GenericFill(db,params,static_cast<IfcDimensionCurveDirectedCallout*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFaceBasedSurfaceModel>(const DB& db, const LIST& params, IfcFaceBasedSurfaceModel* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcFaceBasedSurfaceModel"); } do { // convert the 'FbsmFaces' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->FbsmFaces, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcFaceBasedSurfaceModel to be a `SET [1:?] OF IfcConnectedFaceSet`")); } - } while(0); - return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCraneRailFShapeProfileDef>(const DB& db, const LIST& params, IfcCraneRailFShapeProfileDef* in) +template <> size_t GenericFill<IfcRoundedEdgeFeature>(const DB& db, const LIST& params, IfcRoundedEdgeFeature* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcEdgeFeature*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcColumnType>(const DB& db, const LIST& params, IfcColumnType* in) +template <> size_t GenericFill<IfcElectricDistributionPoint>(const DB& db, const LIST& params, IfcElectricDistributionPoint* in) { - size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowController*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTShapeProfileDef>(const DB& db, const LIST& params, IfcTShapeProfileDef* in) +template <> size_t GenericFill<IfcCableCarrierSegmentType>(const DB& db, const LIST& params, IfcCableCarrierSegmentType* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcEnergyConversionDevice>(const DB& db, const LIST& params, IfcEnergyConversionDevice* in) +template <> size_t GenericFill<IfcWallStandardCase>(const DB& db, const LIST& params, IfcWallStandardCase* in) { - size_t base = GenericFill(db,params,static_cast<IfcDistributionFlowElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcWall*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcWorkSchedule>(const DB& db, const LIST& params, IfcWorkSchedule* in) +template <> size_t GenericFill<IfcCsgSolid>(const DB& db, const LIST& params, IfcCsgSolid* in) { - size_t base = GenericFill(db,params,static_cast<IfcWorkControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcZone>(const DB& db, const LIST& params, IfcZone* in) +template <> size_t GenericFill<IfcBeamType>(const DB& db, const LIST& params, IfcBeamType* in) { - size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcBuildingElementType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcTransportElement>(const DB& db, const LIST& params, IfcTransportElement* in) +template <> size_t GenericFill<IfcAnnotationFillArea>(const DB& db, const LIST& params, IfcAnnotationFillArea* in) { - size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGeometricRepresentationSubContext>(const DB& db, const LIST& params, IfcGeometricRepresentationSubContext* in) +template <> size_t GenericFill<IfcStructuralCurveMemberVarying>(const DB& db, const LIST& params, IfcStructuralCurveMemberVarying* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationContext*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralCurveMember*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLShapeProfileDef>(const DB& db, const LIST& params, IfcLShapeProfileDef* in) +template <> size_t GenericFill<IfcPointOnSurface>(const DB& db, const LIST& params, IfcPointOnSurface* in) { - size_t base = GenericFill(db,params,static_cast<IfcParameterizedProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcPoint*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcGeometricCurveSet>(const DB& db, const LIST& params, IfcGeometricCurveSet* in) +template <> size_t GenericFill<IfcOrderAction>(const DB& db, const LIST& params, IfcOrderAction* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricSet*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcTask*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcActor>(const DB& db, const LIST& params, IfcActor* in) +template <> size_t GenericFill<IfcEdgeLoop>(const DB& db, const LIST& params, IfcEdgeLoop* in) { - size_t base = GenericFill(db,params,static_cast<IfcObject*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcLoop*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOccupant>(const DB& db, const LIST& params, IfcOccupant* in) +template <> size_t GenericFill<IfcAnnotationFillAreaOccurrence>(const DB& db, const LIST& params, IfcAnnotationFillAreaOccurrence* in) { - size_t base = GenericFill(db,params,static_cast<IfcActor*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBooleanClippingResult>(const DB& db, const LIST& params, IfcBooleanClippingResult* in) -{ - size_t base = GenericFill(db,params,static_cast<IfcBooleanResult*>(in)); - if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcBooleanClippingResult"); } return base; -} -// ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAnnotationFillArea>(const DB& db, const LIST& params, IfcAnnotationFillArea* in) +template <> size_t GenericFill<IfcWorkPlan>(const DB& db, const LIST& params, IfcWorkPlan* in) { - size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcWorkControl*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcLightSourceSpot>(const DB& db, const LIST& params, IfcLightSourceSpot* in) +template <> size_t GenericFill<IfcEllipse>(const DB& db, const LIST& params, IfcEllipse* in) { - size_t base = GenericFill(db,params,static_cast<IfcLightSourcePositional*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcConic*>(in)); + if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcEllipse"); } do { // convert the 'SemiAxis1' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->SemiAxis1, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); } + } while(0); + do { // convert the 'SemiAxis2' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->SemiAxis2, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcEllipse to be a `IfcPositiveLengthMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcFireSuppressionTerminalType>(const DB& db, const LIST& params, IfcFireSuppressionTerminalType* in) +template <> size_t GenericFill<IfcProductDefinitionShape>(const DB& db, const LIST& params, IfcProductDefinitionShape* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcProductRepresentation*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcElectricGeneratorType>(const DB& db, const LIST& params, IfcElectricGeneratorType* in) +template <> size_t GenericFill<IfcProjectionCurve>(const DB& db, const LIST& params, IfcProjectionCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcEnergyConversionDeviceType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcAnnotationCurveOccurrence*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcInventory>(const DB& db, const LIST& params, IfcInventory* in) +template <> size_t GenericFill<IfcElectricalCircuit>(const DB& db, const LIST& params, IfcElectricalCircuit* in) { - size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSystem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPolyline>(const DB& db, const LIST& params, IfcPolyline* in) +template <> size_t GenericFill<IfcRationalBezierCurve>(const DB& db, const LIST& params, IfcRationalBezierCurve* in) { - size_t base = GenericFill(db,params,static_cast<IfcBoundedCurve*>(in)); - if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPolyline"); } do { // convert the 'Points' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->Points, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcPolyline to be a `LIST [2:?] OF IfcCartesianPoint`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcBezierCurve*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcBoxedHalfSpace>(const DB& db, const LIST& params, IfcBoxedHalfSpace* in) +template <> size_t GenericFill<IfcStructuralPointAction>(const DB& db, const LIST& params, IfcStructuralPointAction* in) { - size_t base = GenericFill(db,params,static_cast<IfcHalfSpaceSolid*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcStructuralAction*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAirTerminalType>(const DB& db, const LIST& params, IfcAirTerminalType* in) +template <> size_t GenericFill<IfcPipeSegmentType>(const DB& db, const LIST& params, IfcPipeSegmentType* in) { - size_t base = GenericFill(db,params,static_cast<IfcFlowTerminalType*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowSegmentType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcDistributionPort>(const DB& db, const LIST& params, IfcDistributionPort* in) +template <> size_t GenericFill<IfcTwoDirectionRepeatFactor>(const DB& db, const LIST& params, IfcTwoDirectionRepeatFactor* in) { - size_t base = GenericFill(db,params,static_cast<IfcPort*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcOneDirectionRepeatFactor*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCostItem>(const DB& db, const LIST& params, IfcCostItem* in) +template <> size_t GenericFill<IfcShapeRepresentation>(const DB& db, const LIST& params, IfcShapeRepresentation* in) { - size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcShapeModel*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuredDimensionCallout>(const DB& db, const LIST& params, IfcStructuredDimensionCallout* in) +template <> size_t GenericFill<IfcPropertySet>(const DB& db, const LIST& params, IfcPropertySet* in) { - size_t base = GenericFill(db,params,static_cast<IfcDraughtingCallout*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcPropertySetDefinition*>(in)); + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcPropertySet"); } do { // convert the 'HasProperties' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->HasProperties, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcPropertySet to be a `SET [1:?] OF IfcProperty`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcStructuralResultGroup>(const DB& db, const LIST& params, IfcStructuralResultGroup* in) +template <> size_t GenericFill<IfcSurfaceStyleRendering>(const DB& db, const LIST& params, IfcSurfaceStyleRendering* in) { - size_t base = GenericFill(db,params,static_cast<IfcGroup*>(in)); -// this data structure is not used yet, so there is no code generated to fill its members + size_t base = GenericFill(db,params,static_cast<IfcSurfaceStyleShading*>(in)); + if (params.GetSize() < 9) { throw STEP::TypeError("expected 9 arguments to IfcSurfaceStyleRendering"); } do { // convert the 'Transparency' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->Transparency, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcSurfaceStyleRendering to be a `IfcNormalisedRatioMeasure`")); } + } while(0); + do { // convert the 'DiffuseColour' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->DiffuseColour, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } + } while(0); + do { // convert the 'TransmissionColour' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->TransmissionColour, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } + } while(0); + do { // convert the 'DiffuseTransmissionColour' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->DiffuseTransmissionColour, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } + } while(0); + do { // convert the 'ReflectionColour' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->ReflectionColour, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 5 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } + } while(0); + do { // convert the 'SpecularColour' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->SpecularColour, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 6 to IfcSurfaceStyleRendering to be a `IfcColourOrFactor`")); } + } while(0); + do { // convert the 'SpecularHighlight' argument + boost::shared_ptr<const DataType> arg = params[base++]; + if (dynamic_cast<const UNSET*>(&*arg)) break; + try { GenericConvert( in->SpecularHighlight, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 7 to IfcSurfaceStyleRendering to be a `IfcSpecularHighlightSelect`")); } + } while(0); + do { // convert the 'ReflectanceMethod' argument + boost::shared_ptr<const DataType> arg = params[base++]; + try { GenericConvert( in->ReflectanceMethod, arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 8 to IfcSurfaceStyleRendering to be a `IfcReflectanceMethodEnum`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcOrientedEdge>(const DB& db, const LIST& params, IfcOrientedEdge* in) +template <> size_t GenericFill<IfcDistributionPort>(const DB& db, const LIST& params, IfcDistributionPort* in) { - size_t base = GenericFill(db,params,static_cast<IfcEdge*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcPort*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcCsgSolid>(const DB& db, const LIST& params, IfcCsgSolid* in) +template <> size_t GenericFill<IfcPipeFittingType>(const DB& db, const LIST& params, IfcPipeFittingType* in) { - size_t base = GenericFill(db,params,static_cast<IfcSolidModel*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcFlowFittingType*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcPlanarBox>(const DB& db, const LIST& params, IfcPlanarBox* in) +template <> size_t GenericFill<IfcTransportElement>(const DB& db, const LIST& params, IfcTransportElement* in) { - size_t base = GenericFill(db,params,static_cast<IfcPlanarExtent*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcElement*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcMaterialDefinitionRepresentation>(const DB& db, const LIST& params, IfcMaterialDefinitionRepresentation* in) +template <> size_t GenericFill<IfcAnnotationTextOccurrence>(const DB& db, const LIST& params, IfcAnnotationTextOccurrence* in) { - size_t base = GenericFill(db,params,static_cast<IfcProductRepresentation*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcAnnotationOccurrence*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcAsymmetricIShapeProfileDef>(const DB& db, const LIST& params, IfcAsymmetricIShapeProfileDef* in) +template <> size_t GenericFill<IfcStructuralAnalysisModel>(const DB& db, const LIST& params, IfcStructuralAnalysisModel* in) { - size_t base = GenericFill(db,params,static_cast<IfcIShapeProfileDef*>(in)); + size_t base = GenericFill(db,params,static_cast<IfcSystem*>(in)); // this data structure is not used yet, so there is no code generated to fill its members return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill<IfcRepresentationMap>(const DB& db, const LIST& params, IfcRepresentationMap* in) +template <> size_t GenericFill<IfcConditionCriterion>(const DB& db, const LIST& params, IfcConditionCriterion* in) { - size_t base = 0; - if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationMap"); } do { // convert the 'MappingOrigin' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->MappingOrigin, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRepresentationMap to be a `IfcAxis2Placement`")); } - } while(0); - do { // convert the 'MappedRepresentation' argument - boost::shared_ptr<const DataType> arg = params[base++]; - try { GenericConvert( in->MappedRepresentation, arg, db ); break; } - catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRepresentationMap to be a `IfcRepresentation`")); } - } while(0); + size_t base = GenericFill(db,params,static_cast<IfcControl*>(in)); +// this data structure is not used yet, so there is no code generated to fill its members return base; } diff --git a/src/3rdparty/assimp/code/IFCReaderGen.h b/src/3rdparty/assimp/code/IFCReaderGen.h index 300960b2e..d7f831087 100644 --- a/src/3rdparty/assimp/code/IFCReaderGen.h +++ b/src/3rdparty/assimp/code/IFCReaderGen.h @@ -1,8 +1,8 @@ /* -Open Asset Import Library (assimp) +Open Asset Import Library (ASSIMP) ---------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2010, ASSIMP Development Team All rights reserved. Redistribution and use of this software in source and binary forms, @@ -18,10 +18,10 @@ following conditions are met: following disclaimer in the documentation and/or other materials provided with the distribution. -* Neither the name of the assimp team, nor the names of its +* Neither the name of the ASSIMP team, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior - written permission of the assimp team. + written permission of the ASSIMP Development Team. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -61,658 +61,658 @@ namespace IFC { // ****************************************************************************** - // C++ wrapper type for IfcSoundPowerMeasure - typedef REAL IfcSoundPowerMeasure; - // C++ wrapper type for IfcDoorStyleOperationEnum - typedef ENUMERATION IfcDoorStyleOperationEnum; - // C++ wrapper type for IfcRotationalFrequencyMeasure - typedef REAL IfcRotationalFrequencyMeasure; - // C++ wrapper type for IfcCharacterStyleSelect - typedef SELECT IfcCharacterStyleSelect; - // C++ wrapper type for IfcElectricTimeControlTypeEnum - typedef ENUMERATION IfcElectricTimeControlTypeEnum; - // C++ wrapper type for IfcAirTerminalTypeEnum - typedef ENUMERATION IfcAirTerminalTypeEnum; - // C++ wrapper type for IfcProjectOrderTypeEnum - typedef ENUMERATION IfcProjectOrderTypeEnum; + // C++ wrapper type for IfcStairTypeEnum + typedef ENUMERATION IfcStairTypeEnum; + // C++ wrapper type for IfcSpaceTypeEnum + typedef ENUMERATION IfcSpaceTypeEnum; + // C++ wrapper type for IfcWallTypeEnum + typedef ENUMERATION IfcWallTypeEnum; + // C++ wrapper type for IfcMonthInYearNumber + typedef INTEGER IfcMonthInYearNumber; + // C++ wrapper type for IfcHeatFluxDensityMeasure + typedef REAL IfcHeatFluxDensityMeasure; + // C++ wrapper type for IfcKinematicViscosityMeasure + typedef REAL IfcKinematicViscosityMeasure; // C++ wrapper type for IfcSequenceEnum typedef ENUMERATION IfcSequenceEnum; - // C++ wrapper type for IfcSpecificHeatCapacityMeasure - typedef REAL IfcSpecificHeatCapacityMeasure; - // C++ wrapper type for IfcHeatingValueMeasure - typedef REAL IfcHeatingValueMeasure; - // C++ wrapper type for IfcRibPlateDirectionEnum - typedef ENUMERATION IfcRibPlateDirectionEnum; - // C++ wrapper type for IfcSensorTypeEnum - typedef ENUMERATION IfcSensorTypeEnum; - // C++ wrapper type for IfcElectricHeaterTypeEnum - typedef ENUMERATION IfcElectricHeaterTypeEnum; - // C++ wrapper type for IfcObjectiveEnum - typedef ENUMERATION IfcObjectiveEnum; - // C++ wrapper type for IfcTextStyleSelect - typedef SELECT IfcTextStyleSelect; - // C++ wrapper type for IfcColumnTypeEnum - typedef ENUMERATION IfcColumnTypeEnum; - // C++ wrapper type for IfcGasTerminalTypeEnum - typedef ENUMERATION IfcGasTerminalTypeEnum; + // C++ wrapper type for IfcAirToAirHeatRecoveryTypeEnum + typedef ENUMERATION IfcAirToAirHeatRecoveryTypeEnum; + // C++ wrapper type for IfcActorSelect + typedef SELECT IfcActorSelect; + // C++ wrapper type for IfcTransformerTypeEnum + typedef ENUMERATION IfcTransformerTypeEnum; + // C++ wrapper type for IfcUnitaryEquipmentTypeEnum + typedef ENUMERATION IfcUnitaryEquipmentTypeEnum; + // C++ wrapper type for IfcElectricFlowStorageDeviceTypeEnum + typedef ENUMERATION IfcElectricFlowStorageDeviceTypeEnum; + // C++ wrapper type for IfcEnergySequenceEnum + typedef ENUMERATION IfcEnergySequenceEnum; + // C++ wrapper type for IfcWorkControlTypeEnum + typedef ENUMERATION IfcWorkControlTypeEnum; + // C++ wrapper type for IfcCurvatureMeasure + typedef REAL IfcCurvatureMeasure; + // C++ wrapper type for IfcParameterValue + typedef REAL IfcParameterValue; + // C++ wrapper type for IfcAppliedValueSelect + typedef SELECT IfcAppliedValueSelect; + // C++ wrapper type for IfcWarpingConstantMeasure + typedef REAL IfcWarpingConstantMeasure; + // C++ wrapper type for IfcArithmeticOperatorEnum + typedef ENUMERATION IfcArithmeticOperatorEnum; + // C++ wrapper type for IfcLinearForceMeasure + typedef REAL IfcLinearForceMeasure; + // C++ wrapper type for IfcWindowPanelPositionEnum + typedef ENUMERATION IfcWindowPanelPositionEnum; + // C++ wrapper type for IfcFlowMeterTypeEnum + typedef ENUMERATION IfcFlowMeterTypeEnum; + // C++ wrapper type for IfcRampFlightTypeEnum + typedef ENUMERATION IfcRampFlightTypeEnum; + // C++ wrapper type for IfcSpecularHighlightSelect + typedef SELECT IfcSpecularHighlightSelect; + // C++ wrapper type for IfcActionTypeEnum + typedef ENUMERATION IfcActionTypeEnum; + // C++ wrapper type for IfcGeometricProjectionEnum + typedef ENUMERATION IfcGeometricProjectionEnum; + // C++ wrapper type for IfcTimeSeriesDataTypeEnum + typedef ENUMERATION IfcTimeSeriesDataTypeEnum; + // C++ wrapper type for IfcMagneticFluxMeasure + typedef REAL IfcMagneticFluxMeasure; + // C++ wrapper type for IfcObjectTypeEnum + typedef ENUMERATION IfcObjectTypeEnum; + // C++ wrapper type for IfcDataOriginEnum + typedef ENUMERATION IfcDataOriginEnum; // C++ wrapper type for IfcMassDensityMeasure typedef REAL IfcMassDensityMeasure; + // C++ wrapper type for IfcLightFixtureTypeEnum + typedef ENUMERATION IfcLightFixtureTypeEnum; + // C++ wrapper type for IfcServiceLifeTypeEnum + typedef ENUMERATION IfcServiceLifeTypeEnum; + // C++ wrapper type for IfcElectricVoltageMeasure + typedef REAL IfcElectricVoltageMeasure; + // C++ wrapper type for IfcHeatingValueMeasure + typedef REAL IfcHeatingValueMeasure; + // C++ wrapper type for IfcPresentableText + typedef STRING IfcPresentableText; + // C++ wrapper type for IfcAheadOrBehind + typedef ENUMERATION IfcAheadOrBehind; // C++ wrapper type for IfcSimpleValue typedef SELECT IfcSimpleValue; - // C++ wrapper type for IfcElectricConductanceMeasure - typedef REAL IfcElectricConductanceMeasure; - // C++ wrapper type for IfcBuildingElementProxyTypeEnum - typedef ENUMERATION IfcBuildingElementProxyTypeEnum; - // C++ wrapper type for IfcJunctionBoxTypeEnum - typedef ENUMERATION IfcJunctionBoxTypeEnum; - // C++ wrapper type for IfcModulusOfElasticityMeasure - typedef REAL IfcModulusOfElasticityMeasure; - // C++ wrapper type for IfcActionSourceTypeEnum - typedef ENUMERATION IfcActionSourceTypeEnum; - // C++ wrapper type for IfcSIUnitName - typedef ENUMERATION IfcSIUnitName; - // C++ wrapper type for IfcRotationalMassMeasure - typedef REAL IfcRotationalMassMeasure; - // C++ wrapper type for IfcMemberTypeEnum - typedef ENUMERATION IfcMemberTypeEnum; + // C++ wrapper type for IfcSensorTypeEnum + typedef ENUMERATION IfcSensorTypeEnum; + // C++ wrapper type for IfcDerivedUnitEnum + typedef ENUMERATION IfcDerivedUnitEnum; + // C++ wrapper type for IfcSizeSelect + typedef SELECT IfcSizeSelect; + // C++ wrapper type for IfcTransportElementTypeEnum + typedef ENUMERATION IfcTransportElementTypeEnum; + // C++ wrapper type for IfcInventoryTypeEnum + typedef ENUMERATION IfcInventoryTypeEnum; // C++ wrapper type for IfcTextDecoration typedef STRING IfcTextDecoration; - // C++ wrapper type for IfcPositiveLengthMeasure - typedef REAL IfcPositiveLengthMeasure; - // C++ wrapper type for IfcAmountOfSubstanceMeasure - typedef REAL IfcAmountOfSubstanceMeasure; - // C++ wrapper type for IfcDoorStyleConstructionEnum - typedef ENUMERATION IfcDoorStyleConstructionEnum; - // C++ wrapper type for IfcAngularVelocityMeasure - typedef REAL IfcAngularVelocityMeasure; // C++ wrapper type for IfcDirectionSenseEnum typedef ENUMERATION IfcDirectionSenseEnum; - // C++ wrapper type for IfcNullStyle - typedef ENUMERATION IfcNullStyle; - // C++ wrapper type for IfcMonthInYearNumber - typedef INTEGER IfcMonthInYearNumber; - // C++ wrapper type for IfcRampFlightTypeEnum - typedef ENUMERATION IfcRampFlightTypeEnum; - // C++ wrapper type for IfcWindowStyleOperationEnum - typedef ENUMERATION IfcWindowStyleOperationEnum; - // C++ wrapper type for IfcCurvatureMeasure - typedef REAL IfcCurvatureMeasure; - // C++ wrapper type for IfcBooleanOperator - typedef ENUMERATION IfcBooleanOperator; // C++ wrapper type for IfcDuctFittingTypeEnum typedef ENUMERATION IfcDuctFittingTypeEnum; - // C++ wrapper type for IfcCurrencyEnum - typedef ENUMERATION IfcCurrencyEnum; - // C++ wrapper type for IfcObjectTypeEnum - typedef ENUMERATION IfcObjectTypeEnum; - // C++ wrapper type for IfcThermalLoadTypeEnum - typedef ENUMERATION IfcThermalLoadTypeEnum; + // C++ wrapper type for IfcDocumentStatusEnum + typedef ENUMERATION IfcDocumentStatusEnum; + // C++ wrapper type for IfcSlabTypeEnum + typedef ENUMERATION IfcSlabTypeEnum; + // C++ wrapper type for IfcDoorStyleConstructionEnum + typedef ENUMERATION IfcDoorStyleConstructionEnum; + // C++ wrapper type for IfcVolumeMeasure + typedef REAL IfcVolumeMeasure; + // C++ wrapper type for IfcInductanceMeasure + typedef REAL IfcInductanceMeasure; + // C++ wrapper type for IfcCurtainWallTypeEnum + typedef ENUMERATION IfcCurtainWallTypeEnum; + // C++ wrapper type for IfcSIUnitName + typedef ENUMERATION IfcSIUnitName; + // C++ wrapper type for IfcSpecularExponent + typedef REAL IfcSpecularExponent; + // C++ wrapper type for IfcSoundPressureMeasure + typedef REAL IfcSoundPressureMeasure; + // C++ wrapper type for IfcAnalysisTheoryTypeEnum + typedef ENUMERATION IfcAnalysisTheoryTypeEnum; + // C++ wrapper type for IfcGasTerminalTypeEnum + typedef ENUMERATION IfcGasTerminalTypeEnum; + // C++ wrapper type for IfcYearNumber + typedef INTEGER IfcYearNumber; + // C++ wrapper type for IfcModulusOfElasticityMeasure + typedef REAL IfcModulusOfElasticityMeasure; + // C++ wrapper type for IfcChangeActionEnum + typedef ENUMERATION IfcChangeActionEnum; + // C++ wrapper type for IfcDamperTypeEnum + typedef ENUMERATION IfcDamperTypeEnum; + // C++ wrapper type for IfcEvaporatorTypeEnum + typedef ENUMERATION IfcEvaporatorTypeEnum; // C++ wrapper type for IfcIonConcentrationMeasure typedef REAL IfcIonConcentrationMeasure; - // C++ wrapper type for IfcObjectReferenceSelect - typedef SELECT IfcObjectReferenceSelect; + // C++ wrapper type for IfcDuctSegmentTypeEnum + typedef ENUMERATION IfcDuctSegmentTypeEnum; + // C++ wrapper type for IfcProtectiveDeviceTypeEnum + typedef ENUMERATION IfcProtectiveDeviceTypeEnum; + // C++ wrapper type for IfcAbsorbedDoseMeasure + typedef REAL IfcAbsorbedDoseMeasure; + // C++ wrapper type for IfcMassPerLengthMeasure + typedef REAL IfcMassPerLengthMeasure; + // C++ wrapper type for IfcTextFontName + typedef STRING IfcTextFontName; + // C++ wrapper type for IfcOrientationSelect + typedef SELECT IfcOrientationSelect; + // C++ wrapper type for IfcIlluminanceMeasure + typedef REAL IfcIlluminanceMeasure; + // C++ wrapper type for IfcFireSuppressionTerminalTypeEnum + typedef ENUMERATION IfcFireSuppressionTerminalTypeEnum; + // C++ wrapper type for IfcFontStyle + typedef STRING IfcFontStyle; + // C++ wrapper type for IfcMomentOfInertiaMeasure + typedef REAL IfcMomentOfInertiaMeasure; + // C++ wrapper type for IfcModulusOfSubgradeReactionMeasure + typedef REAL IfcModulusOfSubgradeReactionMeasure; + // C++ wrapper type for IfcHumidifierTypeEnum + typedef ENUMERATION IfcHumidifierTypeEnum; + // C++ wrapper type for IfcPresentationStyleSelect + typedef SELECT IfcPresentationStyleSelect; + // C++ wrapper type for IfcThermalTransmittanceMeasure + typedef REAL IfcThermalTransmittanceMeasure; + // C++ wrapper type for IfcRibPlateDirectionEnum + typedef ENUMERATION IfcRibPlateDirectionEnum; // C++ wrapper type for IfcClassificationNotationSelect typedef SELECT IfcClassificationNotationSelect; - // C++ wrapper type for IfcBSplineCurveForm - typedef ENUMERATION IfcBSplineCurveForm; - // C++ wrapper type for IfcElementCompositionEnum - typedef ENUMERATION IfcElementCompositionEnum; - // C++ wrapper type for IfcDraughtingCalloutElement - typedef SELECT IfcDraughtingCalloutElement; - // C++ wrapper type for IfcFillStyleSelect - typedef SELECT IfcFillStyleSelect; - // C++ wrapper type for IfcHeatFluxDensityMeasure - typedef REAL IfcHeatFluxDensityMeasure; - // C++ wrapper type for IfcGeometricProjectionEnum - typedef ENUMERATION IfcGeometricProjectionEnum; - // C++ wrapper type for IfcFontVariant - typedef STRING IfcFontVariant; - // C++ wrapper type for IfcThermalResistanceMeasure - typedef REAL IfcThermalResistanceMeasure; - // C++ wrapper type for IfcReflectanceMethodEnum - typedef ENUMERATION IfcReflectanceMethodEnum; - // C++ wrapper type for IfcSlabTypeEnum - typedef ENUMERATION IfcSlabTypeEnum; - // C++ wrapper type for IfcPositiveRatioMeasure - typedef REAL IfcPositiveRatioMeasure; + // C++ wrapper type for IfcMinuteInHour + typedef INTEGER IfcMinuteInHour; // C++ wrapper type for IfcInternalOrExternalEnum typedef ENUMERATION IfcInternalOrExternalEnum; - // C++ wrapper type for IfcDimensionExtentUsage - typedef ENUMERATION IfcDimensionExtentUsage; - // C++ wrapper type for IfcPipeFittingTypeEnum - typedef ENUMERATION IfcPipeFittingTypeEnum; + // C++ wrapper type for IfcRotationalFrequencyMeasure + typedef REAL IfcRotationalFrequencyMeasure; // C++ wrapper type for IfcSanitaryTerminalTypeEnum typedef ENUMERATION IfcSanitaryTerminalTypeEnum; - // C++ wrapper type for IfcMinuteInHour - typedef INTEGER IfcMinuteInHour; - // C++ wrapper type for IfcWallTypeEnum - typedef ENUMERATION IfcWallTypeEnum; - // C++ wrapper type for IfcMolecularWeightMeasure - typedef REAL IfcMolecularWeightMeasure; - // C++ wrapper type for IfcUnitaryEquipmentTypeEnum - typedef ENUMERATION IfcUnitaryEquipmentTypeEnum; - // C++ wrapper type for IfcProcedureTypeEnum - typedef ENUMERATION IfcProcedureTypeEnum; - // C++ wrapper type for IfcDistributionChamberElementTypeEnum - typedef ENUMERATION IfcDistributionChamberElementTypeEnum; + // C++ wrapper type for IfcSymbolStyleSelect + typedef SELECT IfcSymbolStyleSelect; + // C++ wrapper type for IfcElementCompositionEnum + typedef ENUMERATION IfcElementCompositionEnum; // C++ wrapper type for IfcTextPath typedef ENUMERATION IfcTextPath; - // C++ wrapper type for IfcCostScheduleTypeEnum - typedef ENUMERATION IfcCostScheduleTypeEnum; - // C++ wrapper type for IfcShell - typedef SELECT IfcShell; - // C++ wrapper type for IfcLinearMomentMeasure - typedef REAL IfcLinearMomentMeasure; - // C++ wrapper type for IfcElectricCurrentMeasure - typedef REAL IfcElectricCurrentMeasure; - // C++ wrapper type for IfcDaylightSavingHour - typedef INTEGER IfcDaylightSavingHour; - // C++ wrapper type for IfcNormalisedRatioMeasure - typedef REAL IfcNormalisedRatioMeasure; - // C++ wrapper type for IfcFanTypeEnum - typedef ENUMERATION IfcFanTypeEnum; - // C++ wrapper type for IfcContextDependentMeasure - typedef REAL IfcContextDependentMeasure; - // C++ wrapper type for IfcAheadOrBehind - typedef ENUMERATION IfcAheadOrBehind; - // C++ wrapper type for IfcFontStyle - typedef STRING IfcFontStyle; - // C++ wrapper type for IfcCooledBeamTypeEnum - typedef ENUMERATION IfcCooledBeamTypeEnum; + // C++ wrapper type for IfcPowerMeasure + typedef REAL IfcPowerMeasure; // C++ wrapper type for IfcSurfaceStyleElementSelect typedef SELECT IfcSurfaceStyleElementSelect; - // C++ wrapper type for IfcYearNumber - typedef INTEGER IfcYearNumber; - // C++ wrapper type for IfcLabel - typedef STRING IfcLabel; - // C++ wrapper type for IfcTimeStamp - typedef INTEGER IfcTimeStamp; - // C++ wrapper type for IfcFireSuppressionTerminalTypeEnum - typedef ENUMERATION IfcFireSuppressionTerminalTypeEnum; - // C++ wrapper type for IfcDocumentConfidentialityEnum - typedef ENUMERATION IfcDocumentConfidentialityEnum; - // C++ wrapper type for IfcColourOrFactor - typedef SELECT IfcColourOrFactor; - // C++ wrapper type for IfcAirTerminalBoxTypeEnum - typedef ENUMERATION IfcAirTerminalBoxTypeEnum; - // C++ wrapper type for IfcNumericMeasure - typedef NUMBER IfcNumericMeasure; - // C++ wrapper type for IfcDerivedUnitEnum - typedef ENUMERATION IfcDerivedUnitEnum; - // C++ wrapper type for IfcCurveOrEdgeCurve - typedef SELECT IfcCurveOrEdgeCurve; - // C++ wrapper type for IfcLightEmissionSourceEnum - typedef ENUMERATION IfcLightEmissionSourceEnum; - // C++ wrapper type for IfcKinematicViscosityMeasure - typedef REAL IfcKinematicViscosityMeasure; - // C++ wrapper type for IfcBoxAlignment - typedef STRING IfcBoxAlignment; - // C++ wrapper type for IfcDocumentSelect - typedef SELECT IfcDocumentSelect; - // C++ wrapper type for IfcCableCarrierFittingTypeEnum - typedef ENUMERATION IfcCableCarrierFittingTypeEnum; - // C++ wrapper type for IfcPumpTypeEnum - typedef ENUMERATION IfcPumpTypeEnum; - // C++ wrapper type for IfcHourInDay - typedef INTEGER IfcHourInDay; - // C++ wrapper type for IfcProjectOrderRecordTypeEnum - typedef ENUMERATION IfcProjectOrderRecordTypeEnum; - // C++ wrapper type for IfcWindowStyleConstructionEnum - typedef ENUMERATION IfcWindowStyleConstructionEnum; - // C++ wrapper type for IfcPresentationStyleSelect - typedef SELECT IfcPresentationStyleSelect; - // C++ wrapper type for IfcCableSegmentTypeEnum - typedef ENUMERATION IfcCableSegmentTypeEnum; - // C++ wrapper type for IfcWasteTerminalTypeEnum - typedef ENUMERATION IfcWasteTerminalTypeEnum; - // C++ wrapper type for IfcIsothermalMoistureCapacityMeasure - typedef REAL IfcIsothermalMoistureCapacityMeasure; - // C++ wrapper type for IfcIdentifier - typedef STRING IfcIdentifier; - // C++ wrapper type for IfcRadioActivityMeasure - typedef REAL IfcRadioActivityMeasure; - // C++ wrapper type for IfcSymbolStyleSelect - typedef SELECT IfcSymbolStyleSelect; - // C++ wrapper type for IfcRoofTypeEnum - typedef ENUMERATION IfcRoofTypeEnum; - // C++ wrapper type for IfcReal - typedef REAL IfcReal; - // C++ wrapper type for IfcRoleEnum - typedef ENUMERATION IfcRoleEnum; - // C++ wrapper type for IfcMeasureValue - typedef SELECT IfcMeasureValue; - // C++ wrapper type for IfcPileTypeEnum - typedef ENUMERATION IfcPileTypeEnum; - // C++ wrapper type for IfcElectricCurrentEnum - typedef ENUMERATION IfcElectricCurrentEnum; - // C++ wrapper type for IfcTextTransformation - typedef STRING IfcTextTransformation; - // C++ wrapper type for IfcFilterTypeEnum - typedef ENUMERATION IfcFilterTypeEnum; - // C++ wrapper type for IfcTransformerTypeEnum - typedef ENUMERATION IfcTransformerTypeEnum; - // C++ wrapper type for IfcSurfaceSide - typedef ENUMERATION IfcSurfaceSide; - // C++ wrapper type for IfcThermalTransmittanceMeasure - typedef REAL IfcThermalTransmittanceMeasure; - // C++ wrapper type for IfcTubeBundleTypeEnum - typedef ENUMERATION IfcTubeBundleTypeEnum; - // C++ wrapper type for IfcLightFixtureTypeEnum - typedef ENUMERATION IfcLightFixtureTypeEnum; - // C++ wrapper type for IfcInductanceMeasure - typedef REAL IfcInductanceMeasure; - // C++ wrapper type for IfcGlobalOrLocalEnum - typedef ENUMERATION IfcGlobalOrLocalEnum; - // C++ wrapper type for IfcOutletTypeEnum - typedef ENUMERATION IfcOutletTypeEnum; - // C++ wrapper type for IfcWorkControlTypeEnum - typedef ENUMERATION IfcWorkControlTypeEnum; - // C++ wrapper type for IfcWarpingMomentMeasure - typedef REAL IfcWarpingMomentMeasure; - // C++ wrapper type for IfcDynamicViscosityMeasure - typedef REAL IfcDynamicViscosityMeasure; - // C++ wrapper type for IfcEnergySequenceEnum - typedef ENUMERATION IfcEnergySequenceEnum; - // C++ wrapper type for IfcFillAreaStyleTileShapeSelect - typedef SELECT IfcFillAreaStyleTileShapeSelect; - // C++ wrapper type for IfcPointOrVertexPoint - typedef SELECT IfcPointOrVertexPoint; - // C++ wrapper type for IfcVibrationIsolatorTypeEnum - typedef ENUMERATION IfcVibrationIsolatorTypeEnum; - // C++ wrapper type for IfcTankTypeEnum - typedef ENUMERATION IfcTankTypeEnum; - // C++ wrapper type for IfcTimeSeriesDataTypeEnum - typedef ENUMERATION IfcTimeSeriesDataTypeEnum; - // C++ wrapper type for IfcSurfaceTextureEnum - typedef ENUMERATION IfcSurfaceTextureEnum; - // C++ wrapper type for IfcAddressTypeEnum - typedef ENUMERATION IfcAddressTypeEnum; - // C++ wrapper type for IfcChillerTypeEnum - typedef ENUMERATION IfcChillerTypeEnum; - // C++ wrapper type for IfcLightDistributionCurveEnum - typedef ENUMERATION IfcLightDistributionCurveEnum; - // C++ wrapper type for IfcReinforcingBarRoleEnum - typedef ENUMERATION IfcReinforcingBarRoleEnum; // C++ wrapper type for IfcResourceConsumptionEnum typedef ENUMERATION IfcResourceConsumptionEnum; - // C++ wrapper type for IfcCsgSelect - typedef SELECT IfcCsgSelect; - // C++ wrapper type for IfcModulusOfLinearSubgradeReactionMeasure - typedef REAL IfcModulusOfLinearSubgradeReactionMeasure; - // C++ wrapper type for IfcEvaporatorTypeEnum - typedef ENUMERATION IfcEvaporatorTypeEnum; - // C++ wrapper type for IfcTimeSeriesScheduleTypeEnum - typedef ENUMERATION IfcTimeSeriesScheduleTypeEnum; - // C++ wrapper type for IfcDayInMonthNumber - typedef INTEGER IfcDayInMonthNumber; - // C++ wrapper type for IfcElectricMotorTypeEnum - typedef ENUMERATION IfcElectricMotorTypeEnum; - // C++ wrapper type for IfcThermalConductivityMeasure - typedef REAL IfcThermalConductivityMeasure; - // C++ wrapper type for IfcEnergyMeasure - typedef REAL IfcEnergyMeasure; - // C++ wrapper type for IfcRotationalStiffnessMeasure - typedef REAL IfcRotationalStiffnessMeasure; - // C++ wrapper type for IfcDerivedMeasureValue - typedef SELECT IfcDerivedMeasureValue; - // C++ wrapper type for IfcDoorPanelOperationEnum - typedef ENUMERATION IfcDoorPanelOperationEnum; - // C++ wrapper type for IfcCurveStyleFontSelect - typedef SELECT IfcCurveStyleFontSelect; - // C++ wrapper type for IfcWindowPanelOperationEnum - typedef ENUMERATION IfcWindowPanelOperationEnum; - // C++ wrapper type for IfcDataOriginEnum - typedef ENUMERATION IfcDataOriginEnum; - // C++ wrapper type for IfcStairTypeEnum - typedef ENUMERATION IfcStairTypeEnum; + // C++ wrapper type for IfcElectricCapacitanceMeasure + typedef REAL IfcElectricCapacitanceMeasure; + // C++ wrapper type for IfcLayerSetDirectionEnum + typedef ENUMERATION IfcLayerSetDirectionEnum; // C++ wrapper type for IfcRailingTypeEnum typedef ENUMERATION IfcRailingTypeEnum; - // C++ wrapper type for IfcPowerMeasure - typedef REAL IfcPowerMeasure; + // C++ wrapper type for IfcObjectiveEnum + typedef ENUMERATION IfcObjectiveEnum; + // C++ wrapper type for IfcDocumentSelect + typedef SELECT IfcDocumentSelect; + // C++ wrapper type for IfcModulusOfLinearSubgradeReactionMeasure + typedef REAL IfcModulusOfLinearSubgradeReactionMeasure; + // C++ wrapper type for IfcThermalAdmittanceMeasure + typedef REAL IfcThermalAdmittanceMeasure; + // C++ wrapper type for IfcTransitionCode + typedef ENUMERATION IfcTransitionCode; + // C++ wrapper type for IfcConnectionTypeEnum + typedef ENUMERATION IfcConnectionTypeEnum; + // C++ wrapper type for IfcMonetaryMeasure + typedef REAL IfcMonetaryMeasure; // C++ wrapper type for IfcStackTerminalTypeEnum typedef ENUMERATION IfcStackTerminalTypeEnum; - // C++ wrapper type for IfcHatchLineDistanceSelect - typedef SELECT IfcHatchLineDistanceSelect; - // C++ wrapper type for IfcTrimmingSelect - typedef SELECT IfcTrimmingSelect; - // C++ wrapper type for IfcThermalExpansionCoefficientMeasure - typedef REAL IfcThermalExpansionCoefficientMeasure; - // C++ wrapper type for IfcLightDistributionDataSourceSelect - typedef SELECT IfcLightDistributionDataSourceSelect; - // C++ wrapper type for IfcTorqueMeasure - typedef REAL IfcTorqueMeasure; - // C++ wrapper type for IfcMassPerLengthMeasure - typedef REAL IfcMassPerLengthMeasure; - // C++ wrapper type for IfcValveTypeEnum - typedef ENUMERATION IfcValveTypeEnum; - // C++ wrapper type for IfcWindowPanelPositionEnum - typedef ENUMERATION IfcWindowPanelPositionEnum; - // C++ wrapper type for IfcSurfaceOrFaceSurface - typedef SELECT IfcSurfaceOrFaceSurface; + // C++ wrapper type for IfcColour + typedef SELECT IfcColour; + // C++ wrapper type for IfcText + typedef STRING IfcText; + // C++ wrapper type for IfcContextDependentMeasure + typedef REAL IfcContextDependentMeasure; + // C++ wrapper type for IfcThermalConductivityMeasure + typedef REAL IfcThermalConductivityMeasure; + // C++ wrapper type for IfcProjectedOrTrueLengthEnum + typedef ENUMERATION IfcProjectedOrTrueLengthEnum; + // C++ wrapper type for IfcPressureMeasure + typedef REAL IfcPressureMeasure; + // C++ wrapper type for IfcMoistureDiffusivityMeasure + typedef REAL IfcMoistureDiffusivityMeasure; + // C++ wrapper type for IfcBooleanOperator + typedef ENUMERATION IfcBooleanOperator; // C++ wrapper type for IfcPropertySourceEnum typedef ENUMERATION IfcPropertySourceEnum; - // C++ wrapper type for IfcCableCarrierSegmentTypeEnum - typedef ENUMERATION IfcCableCarrierSegmentTypeEnum; - // C++ wrapper type for IfcCountMeasure - typedef NUMBER IfcCountMeasure; - // C++ wrapper type for IfcFontWeight - typedef STRING IfcFontWeight; - // C++ wrapper type for IfcPhysicalOrVirtualEnum - typedef ENUMERATION IfcPhysicalOrVirtualEnum; - // C++ wrapper type for IfcSpaceTypeEnum - typedef ENUMERATION IfcSpaceTypeEnum; - // C++ wrapper type for IfcVolumetricFlowRateMeasure - typedef REAL IfcVolumetricFlowRateMeasure; - // C++ wrapper type for IfcLuminousFluxMeasure - typedef REAL IfcLuminousFluxMeasure; - // C++ wrapper type for IfcEvaporativeCoolerTypeEnum - typedef ENUMERATION IfcEvaporativeCoolerTypeEnum; - // C++ wrapper type for IfcLayeredItem - typedef SELECT IfcLayeredItem; - // C++ wrapper type for IfcModulusOfSubgradeReactionMeasure - typedef REAL IfcModulusOfSubgradeReactionMeasure; - // C++ wrapper type for IfcHeatExchangerTypeEnum - typedef ENUMERATION IfcHeatExchangerTypeEnum; - // C++ wrapper type for IfcProtectiveDeviceTypeEnum - typedef ENUMERATION IfcProtectiveDeviceTypeEnum; - // C++ wrapper type for IfcDamperTypeEnum - typedef ENUMERATION IfcDamperTypeEnum; - // C++ wrapper type for IfcControllerTypeEnum - typedef ENUMERATION IfcControllerTypeEnum; - // C++ wrapper type for IfcMassFlowRateMeasure - typedef REAL IfcMassFlowRateMeasure; - // C++ wrapper type for IfcAssemblyPlaceEnum - typedef ENUMERATION IfcAssemblyPlaceEnum; - // C++ wrapper type for IfcAreaMeasure - typedef REAL IfcAreaMeasure; - // C++ wrapper type for IfcServiceLifeFactorTypeEnum - typedef ENUMERATION IfcServiceLifeFactorTypeEnum; - // C++ wrapper type for IfcVolumeMeasure - typedef REAL IfcVolumeMeasure; - // C++ wrapper type for IfcBeamTypeEnum - typedef ENUMERATION IfcBeamTypeEnum; - // C++ wrapper type for IfcStateEnum - typedef ENUMERATION IfcStateEnum; - // C++ wrapper type for IfcSpaceHeaterTypeEnum - typedef ENUMERATION IfcSpaceHeaterTypeEnum; - // C++ wrapper type for IfcSectionTypeEnum - typedef ENUMERATION IfcSectionTypeEnum; - // C++ wrapper type for IfcFootingTypeEnum - typedef ENUMERATION IfcFootingTypeEnum; - // C++ wrapper type for IfcMonetaryMeasure - typedef REAL IfcMonetaryMeasure; - // C++ wrapper type for IfcLoadGroupTypeEnum - typedef ENUMERATION IfcLoadGroupTypeEnum; - // C++ wrapper type for IfcElectricGeneratorTypeEnum - typedef ENUMERATION IfcElectricGeneratorTypeEnum; - // C++ wrapper type for IfcFlowMeterTypeEnum - typedef ENUMERATION IfcFlowMeterTypeEnum; + // C++ wrapper type for IfcTimeStamp + typedef INTEGER IfcTimeStamp; // C++ wrapper type for IfcMaterialSelect typedef SELECT IfcMaterialSelect; - // C++ wrapper type for IfcAnalysisModelTypeEnum - typedef ENUMERATION IfcAnalysisModelTypeEnum; - // C++ wrapper type for IfcTemperatureGradientMeasure - typedef REAL IfcTemperatureGradientMeasure; - // C++ wrapper type for IfcModulusOfRotationalSubgradeReactionMeasure - typedef REAL IfcModulusOfRotationalSubgradeReactionMeasure; - // C++ wrapper type for IfcColour - typedef SELECT IfcColour; - // C++ wrapper type for IfcCurtainWallTypeEnum - typedef ENUMERATION IfcCurtainWallTypeEnum; - // C++ wrapper type for IfcMetricValueSelect - typedef SELECT IfcMetricValueSelect; - // C++ wrapper type for IfcTextAlignment - typedef STRING IfcTextAlignment; - // C++ wrapper type for IfcDoorPanelPositionEnum - typedef ENUMERATION IfcDoorPanelPositionEnum; - // C++ wrapper type for IfcPlateTypeEnum - typedef ENUMERATION IfcPlateTypeEnum; - // C++ wrapper type for IfcSectionalAreaIntegralMeasure - typedef REAL IfcSectionalAreaIntegralMeasure; - // C++ wrapper type for IfcPresentableText - typedef STRING IfcPresentableText; + // C++ wrapper type for IfcGloballyUniqueId + typedef STRING IfcGloballyUniqueId; + // C++ wrapper type for IfcReflectanceMethodEnum + typedef ENUMERATION IfcReflectanceMethodEnum; // C++ wrapper type for IfcVaporPermeabilityMeasure typedef REAL IfcVaporPermeabilityMeasure; - // C++ wrapper type for IfcStructuralSurfaceTypeEnum - typedef ENUMERATION IfcStructuralSurfaceTypeEnum; + // C++ wrapper type for IfcTimeSeriesScheduleTypeEnum + typedef ENUMERATION IfcTimeSeriesScheduleTypeEnum; + // C++ wrapper type for IfcLinearMomentMeasure + typedef REAL IfcLinearMomentMeasure; + // C++ wrapper type for IfcGeometricSetSelect + typedef SELECT IfcGeometricSetSelect; + // C++ wrapper type for IfcSectionModulusMeasure + typedef REAL IfcSectionModulusMeasure; + // C++ wrapper type for IfcBSplineCurveForm + typedef ENUMERATION IfcBSplineCurveForm; + // C++ wrapper type for IfcDimensionExtentUsage + typedef ENUMERATION IfcDimensionExtentUsage; + // C++ wrapper type for IfcThermalExpansionCoefficientMeasure + typedef REAL IfcThermalExpansionCoefficientMeasure; + // C++ wrapper type for IfcHourInDay + typedef INTEGER IfcHourInDay; // C++ wrapper type for IfcLinearVelocityMeasure typedef REAL IfcLinearVelocityMeasure; - // C++ wrapper type for IfcIntegerCountRateMeasure - typedef INTEGER IfcIntegerCountRateMeasure; - // C++ wrapper type for IfcAirToAirHeatRecoveryTypeEnum - typedef ENUMERATION IfcAirToAirHeatRecoveryTypeEnum; - // C++ wrapper type for IfcDocumentStatusEnum - typedef ENUMERATION IfcDocumentStatusEnum; - // C++ wrapper type for IfcLengthMeasure - typedef REAL IfcLengthMeasure; - // C++ wrapper type for IfcPlanarForceMeasure - typedef REAL IfcPlanarForceMeasure; - // C++ wrapper type for IfcBooleanOperand - typedef SELECT IfcBooleanOperand; - // C++ wrapper type for IfcInteger - typedef INTEGER IfcInteger; - // C++ wrapper type for IfcRampTypeEnum - typedef ENUMERATION IfcRampTypeEnum; - // C++ wrapper type for IfcActorSelect - typedef SELECT IfcActorSelect; + // C++ wrapper type for IfcTorqueMeasure + typedef REAL IfcTorqueMeasure; + // C++ wrapper type for IfcTemperatureGradientMeasure + typedef REAL IfcTemperatureGradientMeasure; + // C++ wrapper type for IfcFillStyleSelect + typedef SELECT IfcFillStyleSelect; // C++ wrapper type for IfcElectricChargeMeasure typedef REAL IfcElectricChargeMeasure; - // C++ wrapper type for IfcGeometricSetSelect - typedef SELECT IfcGeometricSetSelect; - // C++ wrapper type for IfcConnectionTypeEnum - typedef ENUMERATION IfcConnectionTypeEnum; - // C++ wrapper type for IfcValue - typedef SELECT IfcValue; + // C++ wrapper type for IfcHeatExchangerTypeEnum + typedef ENUMERATION IfcHeatExchangerTypeEnum; + // C++ wrapper type for IfcElectricCurrentEnum + typedef ENUMERATION IfcElectricCurrentEnum; + // C++ wrapper type for IfcDaylightSavingHour + typedef INTEGER IfcDaylightSavingHour; + // C++ wrapper type for IfcShell + typedef SELECT IfcShell; + // C++ wrapper type for IfcDoseEquivalentMeasure + typedef REAL IfcDoseEquivalentMeasure; + // C++ wrapper type for IfcProjectOrderTypeEnum + typedef ENUMERATION IfcProjectOrderTypeEnum; + // C++ wrapper type for IfcDerivedMeasureValue + typedef SELECT IfcDerivedMeasureValue; + // C++ wrapper type for IfcLightDistributionCurveEnum + typedef ENUMERATION IfcLightDistributionCurveEnum; + // C++ wrapper type for IfcWarpingMomentMeasure + typedef REAL IfcWarpingMomentMeasure; + // C++ wrapper type for IfcMemberTypeEnum + typedef ENUMERATION IfcMemberTypeEnum; + // C++ wrapper type for IfcSoundPowerMeasure + typedef REAL IfcSoundPowerMeasure; + // C++ wrapper type for IfcTextAlignment + typedef STRING IfcTextAlignment; + // C++ wrapper type for IfcCurveOrEdgeCurve + typedef SELECT IfcCurveOrEdgeCurve; + // C++ wrapper type for IfcMassFlowRateMeasure + typedef REAL IfcMassFlowRateMeasure; + // C++ wrapper type for IfcIsothermalMoistureCapacityMeasure + typedef REAL IfcIsothermalMoistureCapacityMeasure; + // C++ wrapper type for IfcCsgSelect + typedef SELECT IfcCsgSelect; // C++ wrapper type for IfcCoolingTowerTypeEnum typedef ENUMERATION IfcCoolingTowerTypeEnum; - // C++ wrapper type for IfcPlaneAngleMeasure - typedef REAL IfcPlaneAngleMeasure; - // C++ wrapper type for IfcSwitchingDeviceTypeEnum - typedef ENUMERATION IfcSwitchingDeviceTypeEnum; + // C++ wrapper type for IfcMassMeasure + typedef REAL IfcMassMeasure; + // C++ wrapper type for IfcPileConstructionEnum + typedef ENUMERATION IfcPileConstructionEnum; + // C++ wrapper type for IfcDoorStyleOperationEnum + typedef ENUMERATION IfcDoorStyleOperationEnum; // C++ wrapper type for IfcFlowDirectionEnum typedef ENUMERATION IfcFlowDirectionEnum; // C++ wrapper type for IfcThermalLoadSourceEnum typedef ENUMERATION IfcThermalLoadSourceEnum; - // C++ wrapper type for IfcTextFontSelect - typedef SELECT IfcTextFontSelect; - // C++ wrapper type for IfcSpecularHighlightSelect - typedef SELECT IfcSpecularHighlightSelect; - // C++ wrapper type for IfcAnalysisTheoryTypeEnum - typedef ENUMERATION IfcAnalysisTheoryTypeEnum; - // C++ wrapper type for IfcTextFontName - typedef STRING IfcTextFontName; - // C++ wrapper type for IfcElectricVoltageMeasure - typedef REAL IfcElectricVoltageMeasure; - // C++ wrapper type for IfcTendonTypeEnum - typedef ENUMERATION IfcTendonTypeEnum; - // C++ wrapper type for IfcSoundPressureMeasure - typedef REAL IfcSoundPressureMeasure; - // C++ wrapper type for IfcElectricDistributionPointFunctionEnum - typedef ENUMERATION IfcElectricDistributionPointFunctionEnum; - // C++ wrapper type for IfcSpecularRoughness - typedef REAL IfcSpecularRoughness; - // C++ wrapper type for IfcActionTypeEnum - typedef ENUMERATION IfcActionTypeEnum; + // C++ wrapper type for IfcLengthMeasure + typedef REAL IfcLengthMeasure; + // C++ wrapper type for IfcConstraintEnum + typedef ENUMERATION IfcConstraintEnum; + // C++ wrapper type for IfcAxis2Placement + typedef SELECT IfcAxis2Placement; + // C++ wrapper type for IfcLoadGroupTypeEnum + typedef ENUMERATION IfcLoadGroupTypeEnum; + // C++ wrapper type for IfcValue + typedef SELECT IfcValue; // C++ wrapper type for IfcReinforcingBarSurfaceEnum typedef ENUMERATION IfcReinforcingBarSurfaceEnum; - // C++ wrapper type for IfcHumidifierTypeEnum - typedef ENUMERATION IfcHumidifierTypeEnum; - // C++ wrapper type for IfcIlluminanceMeasure - typedef REAL IfcIlluminanceMeasure; - // C++ wrapper type for IfcLibrarySelect - typedef SELECT IfcLibrarySelect; - // C++ wrapper type for IfcText - typedef STRING IfcText; - // C++ wrapper type for IfcLayerSetDirectionEnum - typedef ENUMERATION IfcLayerSetDirectionEnum; - // C++ wrapper type for IfcBoilerTypeEnum - typedef ENUMERATION IfcBoilerTypeEnum; - // C++ wrapper type for IfcTimeMeasure - typedef REAL IfcTimeMeasure; + // C++ wrapper type for IfcProjectOrderRecordTypeEnum + typedef ENUMERATION IfcProjectOrderRecordTypeEnum; + // C++ wrapper type for IfcDateTimeSelect + typedef SELECT IfcDateTimeSelect; + // C++ wrapper type for IfcStructuralSurfaceTypeEnum + typedef ENUMERATION IfcStructuralSurfaceTypeEnum; + // C++ wrapper type for IfcPermeableCoveringOperationEnum + typedef ENUMERATION IfcPermeableCoveringOperationEnum; + // C++ wrapper type for IfcFontWeight + typedef STRING IfcFontWeight; + // C++ wrapper type for IfcPHMeasure + typedef REAL IfcPHMeasure; + // C++ wrapper type for IfcDescriptiveMeasure + typedef STRING IfcDescriptiveMeasure; + // C++ wrapper type for IfcCurveStyleFontSelect + typedef SELECT IfcCurveStyleFontSelect; + // C++ wrapper type for IfcUnit + typedef SELECT IfcUnit; + // C++ wrapper type for IfcHatchLineDistanceSelect + typedef SELECT IfcHatchLineDistanceSelect; + // C++ wrapper type for IfcTextStyleSelect + typedef SELECT IfcTextStyleSelect; + // C++ wrapper type for IfcMetricValueSelect + typedef SELECT IfcMetricValueSelect; + // C++ wrapper type for IfcVectorOrDirection + typedef SELECT IfcVectorOrDirection; + // C++ wrapper type for IfcAssemblyPlaceEnum + typedef ENUMERATION IfcAssemblyPlaceEnum; + // C++ wrapper type for IfcAirTerminalTypeEnum + typedef ENUMERATION IfcAirTerminalTypeEnum; + // C++ wrapper type for IfcCoveringTypeEnum + typedef ENUMERATION IfcCoveringTypeEnum; + // C++ wrapper type for IfcPlanarForceMeasure + typedef REAL IfcPlanarForceMeasure; + // C++ wrapper type for IfcValveTypeEnum + typedef ENUMERATION IfcValveTypeEnum; + // C++ wrapper type for IfcAlarmTypeEnum + typedef ENUMERATION IfcAlarmTypeEnum; + // C++ wrapper type for IfcDynamicViscosityMeasure + typedef REAL IfcDynamicViscosityMeasure; + // C++ wrapper type for IfcCurrencyEnum + typedef ENUMERATION IfcCurrencyEnum; + // C++ wrapper type for IfcModulusOfRotationalSubgradeReactionMeasure + typedef REAL IfcModulusOfRotationalSubgradeReactionMeasure; + // C++ wrapper type for IfcCableCarrierFittingTypeEnum + typedef ENUMERATION IfcCableCarrierFittingTypeEnum; + // C++ wrapper type for IfcBoolean + typedef BOOLEAN IfcBoolean; + // C++ wrapper type for IfcActionSourceTypeEnum + typedef ENUMERATION IfcActionSourceTypeEnum; + // C++ wrapper type for IfcStructuralActivityAssignmentSelect + typedef SELECT IfcStructuralActivityAssignmentSelect; + // C++ wrapper type for IfcDistributionChamberElementTypeEnum + typedef ENUMERATION IfcDistributionChamberElementTypeEnum; + // C++ wrapper type for IfcEvaporativeCoolerTypeEnum + typedef ENUMERATION IfcEvaporativeCoolerTypeEnum; + // C++ wrapper type for IfcMagneticFluxDensityMeasure + typedef REAL IfcMagneticFluxDensityMeasure; + // C++ wrapper type for IfcLightDistributionDataSourceSelect + typedef SELECT IfcLightDistributionDataSourceSelect; + // C++ wrapper type for IfcTubeBundleTypeEnum + typedef ENUMERATION IfcTubeBundleTypeEnum; // C++ wrapper type for IfcAccelerationMeasure typedef REAL IfcAccelerationMeasure; - // C++ wrapper type for IfcElectricFlowStorageDeviceTypeEnum - typedef ENUMERATION IfcElectricFlowStorageDeviceTypeEnum; - // C++ wrapper type for IfcLuminousIntensityMeasure - typedef REAL IfcLuminousIntensityMeasure; + // C++ wrapper type for IfcBoilerTypeEnum + typedef ENUMERATION IfcBoilerTypeEnum; + // C++ wrapper type for IfcRampTypeEnum + typedef ENUMERATION IfcRampTypeEnum; + // C++ wrapper type for IfcLuminousIntensityDistributionMeasure + typedef REAL IfcLuminousIntensityDistributionMeasure; + // C++ wrapper type for IfcTrimmingPreference + typedef ENUMERATION IfcTrimmingPreference; + // C++ wrapper type for IfcSpecificHeatCapacityMeasure + typedef REAL IfcSpecificHeatCapacityMeasure; + // C++ wrapper type for IfcAmountOfSubstanceMeasure + typedef REAL IfcAmountOfSubstanceMeasure; + // C++ wrapper type for IfcRoleEnum + typedef ENUMERATION IfcRoleEnum; + // C++ wrapper type for IfcDocumentConfidentialityEnum + typedef ENUMERATION IfcDocumentConfidentialityEnum; + // C++ wrapper type for IfcFrequencyMeasure + typedef REAL IfcFrequencyMeasure; + // C++ wrapper type for IfcSectionTypeEnum + typedef ENUMERATION IfcSectionTypeEnum; + // C++ wrapper type for IfcElementAssemblyTypeEnum + typedef ENUMERATION IfcElementAssemblyTypeEnum; + // C++ wrapper type for IfcFootingTypeEnum + typedef ENUMERATION IfcFootingTypeEnum; + // C++ wrapper type for IfcLayeredItem + typedef SELECT IfcLayeredItem; + // C++ wrapper type for IfcCableSegmentTypeEnum + typedef ENUMERATION IfcCableSegmentTypeEnum; // C++ wrapper type for IfcDefinedSymbolSelect typedef SELECT IfcDefinedSymbolSelect; + // C++ wrapper type for IfcBuildingElementProxyTypeEnum + typedef ENUMERATION IfcBuildingElementProxyTypeEnum; + // C++ wrapper type for IfcElectricGeneratorTypeEnum + typedef ENUMERATION IfcElectricGeneratorTypeEnum; + // C++ wrapper type for IfcRotationalStiffnessMeasure + typedef REAL IfcRotationalStiffnessMeasure; + // C++ wrapper type for IfcSpaceHeaterTypeEnum + typedef ENUMERATION IfcSpaceHeaterTypeEnum; + // C++ wrapper type for IfcAreaMeasure + typedef REAL IfcAreaMeasure; + // C++ wrapper type for IfcLabel + typedef STRING IfcLabel; + // C++ wrapper type for IfcCostScheduleTypeEnum + typedef ENUMERATION IfcCostScheduleTypeEnum; + // C++ wrapper type for IfcSwitchingDeviceTypeEnum + typedef ENUMERATION IfcSwitchingDeviceTypeEnum; + // C++ wrapper type for IfcElectricTimeControlTypeEnum + typedef ENUMERATION IfcElectricTimeControlTypeEnum; + // C++ wrapper type for IfcFilterTypeEnum + typedef ENUMERATION IfcFilterTypeEnum; + // C++ wrapper type for IfcPositiveLengthMeasure + typedef REAL IfcPositiveLengthMeasure; + // C++ wrapper type for IfcNullStyle + typedef ENUMERATION IfcNullStyle; + // C++ wrapper type for IfcConditionCriterionSelect + typedef SELECT IfcConditionCriterionSelect; + // C++ wrapper type for IfcShearModulusMeasure + typedef REAL IfcShearModulusMeasure; + // C++ wrapper type for IfcNormalisedRatioMeasure + typedef REAL IfcNormalisedRatioMeasure; + // C++ wrapper type for IfcDoorPanelOperationEnum + typedef ENUMERATION IfcDoorPanelOperationEnum; + // C++ wrapper type for IfcPointOrVertexPoint + typedef SELECT IfcPointOrVertexPoint; + // C++ wrapper type for IfcRoofTypeEnum + typedef ENUMERATION IfcRoofTypeEnum; + // C++ wrapper type for IfcCountMeasure + typedef NUMBER IfcCountMeasure; + // C++ wrapper type for IfcElectricConductanceMeasure + typedef REAL IfcElectricConductanceMeasure; + // C++ wrapper type for IfcProcedureTypeEnum + typedef ENUMERATION IfcProcedureTypeEnum; + // C++ wrapper type for IfcFlowInstrumentTypeEnum + typedef ENUMERATION IfcFlowInstrumentTypeEnum; + // C++ wrapper type for IfcElectricMotorTypeEnum + typedef ENUMERATION IfcElectricMotorTypeEnum; + // C++ wrapper type for IfcSurfaceSide + typedef ENUMERATION IfcSurfaceSide; + // C++ wrapper type for IfcStructuralCurveTypeEnum + typedef ENUMERATION IfcStructuralCurveTypeEnum; + // C++ wrapper type for IfcCondenserTypeEnum + typedef ENUMERATION IfcCondenserTypeEnum; + // C++ wrapper type for IfcLinearStiffnessMeasure + typedef REAL IfcLinearStiffnessMeasure; // C++ wrapper type for IfcUnitEnum typedef ENUMERATION IfcUnitEnum; - // C++ wrapper type for IfcInventoryTypeEnum - typedef ENUMERATION IfcInventoryTypeEnum; - // C++ wrapper type for IfcStructuralActivityAssignmentSelect - typedef SELECT IfcStructuralActivityAssignmentSelect; - // C++ wrapper type for IfcElementAssemblyTypeEnum - typedef ENUMERATION IfcElementAssemblyTypeEnum; - // C++ wrapper type for IfcServiceLifeTypeEnum - typedef ENUMERATION IfcServiceLifeTypeEnum; - // C++ wrapper type for IfcCoveringTypeEnum - typedef ENUMERATION IfcCoveringTypeEnum; - // C++ wrapper type for IfcStairFlightTypeEnum - typedef ENUMERATION IfcStairFlightTypeEnum; + // C++ wrapper type for IfcOccupantTypeEnum + typedef ENUMERATION IfcOccupantTypeEnum; + // C++ wrapper type for IfcThermalLoadTypeEnum + typedef ENUMERATION IfcThermalLoadTypeEnum; + // C++ wrapper type for IfcReinforcingBarRoleEnum + typedef ENUMERATION IfcReinforcingBarRoleEnum; + // C++ wrapper type for IfcBenchmarkEnum + typedef ENUMERATION IfcBenchmarkEnum; + // C++ wrapper type for IfcPositivePlaneAngleMeasure + typedef REAL IfcPositivePlaneAngleMeasure; + // C++ wrapper type for IfcTextTransformation + typedef STRING IfcTextTransformation; + // C++ wrapper type for IfcDraughtingCalloutElement + typedef SELECT IfcDraughtingCalloutElement; + // C++ wrapper type for IfcRatioMeasure + typedef REAL IfcRatioMeasure; + // C++ wrapper type for IfcSolidAngleMeasure + typedef REAL IfcSolidAngleMeasure; + // C++ wrapper type for IfcPipeSegmentTypeEnum + typedef ENUMERATION IfcPipeSegmentTypeEnum; + // C++ wrapper type for IfcCableCarrierSegmentTypeEnum + typedef ENUMERATION IfcCableCarrierSegmentTypeEnum; + // C++ wrapper type for IfcColourOrFactor + typedef SELECT IfcColourOrFactor; + // C++ wrapper type for IfcIdentifier + typedef STRING IfcIdentifier; + // C++ wrapper type for IfcTendonTypeEnum + typedef ENUMERATION IfcTendonTypeEnum; + // C++ wrapper type for IfcControllerTypeEnum + typedef ENUMERATION IfcControllerTypeEnum; + // C++ wrapper type for IfcRadioActivityMeasure + typedef REAL IfcRadioActivityMeasure; + // C++ wrapper type for IfcTimeMeasure + typedef REAL IfcTimeMeasure; + // C++ wrapper type for IfcPumpTypeEnum + typedef ENUMERATION IfcPumpTypeEnum; + // C++ wrapper type for IfcElectricHeaterTypeEnum + typedef ENUMERATION IfcElectricHeaterTypeEnum; + // C++ wrapper type for IfcBeamTypeEnum + typedef ENUMERATION IfcBeamTypeEnum; + // C++ wrapper type for IfcStateEnum + typedef ENUMERATION IfcStateEnum; // C++ wrapper type for IfcSIPrefix typedef ENUMERATION IfcSIPrefix; - // C++ wrapper type for IfcElectricCapacitanceMeasure - typedef REAL IfcElectricCapacitanceMeasure; - // C++ wrapper type for IfcFlowInstrumentTypeEnum - typedef ENUMERATION IfcFlowInstrumentTypeEnum; + // C++ wrapper type for IfcNumericMeasure + typedef NUMBER IfcNumericMeasure; + // C++ wrapper type for IfcOutletTypeEnum + typedef ENUMERATION IfcOutletTypeEnum; + // C++ wrapper type for IfcCompoundPlaneAngleMeasure + typedef ListOf< INTEGER, 3, 3 > IfcCompoundPlaneAngleMeasure; + // C++ wrapper type for IfcServiceLifeFactorTypeEnum + typedef ENUMERATION IfcServiceLifeFactorTypeEnum; + // C++ wrapper type for IfcLogicalOperatorEnum + typedef ENUMERATION IfcLogicalOperatorEnum; + // C++ wrapper type for IfcBooleanOperand + typedef SELECT IfcBooleanOperand; + // C++ wrapper type for IfcObjectReferenceSelect + typedef SELECT IfcObjectReferenceSelect; + // C++ wrapper type for IfcCooledBeamTypeEnum + typedef ENUMERATION IfcCooledBeamTypeEnum; + // C++ wrapper type for IfcDuctSilencerTypeEnum + typedef ENUMERATION IfcDuctSilencerTypeEnum; + // C++ wrapper type for IfcSectionalAreaIntegralMeasure + typedef REAL IfcSectionalAreaIntegralMeasure; + // C++ wrapper type for IfcFontVariant + typedef STRING IfcFontVariant; + // C++ wrapper type for IfcVolumetricFlowRateMeasure + typedef REAL IfcVolumetricFlowRateMeasure; + // C++ wrapper type for IfcPlateTypeEnum + typedef ENUMERATION IfcPlateTypeEnum; + // C++ wrapper type for IfcEnvironmentalImpactCategoryEnum + typedef ENUMERATION IfcEnvironmentalImpactCategoryEnum; + // C++ wrapper type for IfcVibrationIsolatorTypeEnum + typedef ENUMERATION IfcVibrationIsolatorTypeEnum; // C++ wrapper type for IfcThermodynamicTemperatureMeasure typedef REAL IfcThermodynamicTemperatureMeasure; - // C++ wrapper type for IfcGloballyUniqueId - typedef STRING IfcGloballyUniqueId; - // C++ wrapper type for IfcLampTypeEnum - typedef ENUMERATION IfcLampTypeEnum; - // C++ wrapper type for IfcMagneticFluxMeasure - typedef REAL IfcMagneticFluxMeasure; - // C++ wrapper type for IfcSolidAngleMeasure - typedef REAL IfcSolidAngleMeasure; - // C++ wrapper type for IfcFrequencyMeasure - typedef REAL IfcFrequencyMeasure; - // C++ wrapper type for IfcTransportElementTypeEnum - typedef ENUMERATION IfcTransportElementTypeEnum; - // C++ wrapper type for IfcSoundScaleEnum - typedef ENUMERATION IfcSoundScaleEnum; - // C++ wrapper type for IfcPHMeasure - typedef REAL IfcPHMeasure; - // C++ wrapper type for IfcActuatorTypeEnum - typedef ENUMERATION IfcActuatorTypeEnum; - // C++ wrapper type for IfcPositivePlaneAngleMeasure - typedef REAL IfcPositivePlaneAngleMeasure; - // C++ wrapper type for IfcAppliedValueSelect - typedef SELECT IfcAppliedValueSelect; + // C++ wrapper type for IfcRotationalMassMeasure + typedef REAL IfcRotationalMassMeasure; // C++ wrapper type for IfcSecondInMinute typedef REAL IfcSecondInMinute; - // C++ wrapper type for IfcDuctSegmentTypeEnum - typedef ENUMERATION IfcDuctSegmentTypeEnum; - // C++ wrapper type for IfcThermalAdmittanceMeasure - typedef REAL IfcThermalAdmittanceMeasure; - // C++ wrapper type for IfcSpecularExponent - typedef REAL IfcSpecularExponent; - // C++ wrapper type for IfcDateTimeSelect - typedef SELECT IfcDateTimeSelect; - // C++ wrapper type for IfcTransitionCode - typedef ENUMERATION IfcTransitionCode; + // C++ wrapper type for IfcDayInMonthNumber + typedef INTEGER IfcDayInMonthNumber; // C++ wrapper type for IfcDimensionCount typedef INTEGER IfcDimensionCount; - // C++ wrapper type for IfcLinearStiffnessMeasure - typedef REAL IfcLinearStiffnessMeasure; - // C++ wrapper type for IfcCompoundPlaneAngleMeasure - typedef ListOf< INTEGER, 3, 3 > IfcCompoundPlaneAngleMeasure; - // C++ wrapper type for IfcElectricApplianceTypeEnum - typedef ENUMERATION IfcElectricApplianceTypeEnum; + // C++ wrapper type for IfcWindowStyleOperationEnum + typedef ENUMERATION IfcWindowStyleOperationEnum; + // C++ wrapper type for IfcThermalResistanceMeasure + typedef REAL IfcThermalResistanceMeasure; + // C++ wrapper type for IfcMeasureValue + typedef SELECT IfcMeasureValue; + // C++ wrapper type for IfcWindowPanelOperationEnum + typedef ENUMERATION IfcWindowPanelOperationEnum; + // C++ wrapper type for IfcChillerTypeEnum + typedef ENUMERATION IfcChillerTypeEnum; + // C++ wrapper type for IfcPositiveRatioMeasure + typedef REAL IfcPositiveRatioMeasure; + // C++ wrapper type for IfcInteger + typedef INTEGER IfcInteger; + // C++ wrapper type for IfcLogical + typedef LOGICAL IfcLogical; + // C++ wrapper type for IfcJunctionBoxTypeEnum + typedef ENUMERATION IfcJunctionBoxTypeEnum; + // C++ wrapper type for IfcAddressTypeEnum + typedef ENUMERATION IfcAddressTypeEnum; + // C++ wrapper type for IfcWasteTerminalTypeEnum + typedef ENUMERATION IfcWasteTerminalTypeEnum; + // C++ wrapper type for IfcTrimmingSelect + typedef SELECT IfcTrimmingSelect; + // C++ wrapper type for IfcLightEmissionSourceEnum + typedef ENUMERATION IfcLightEmissionSourceEnum; + // C++ wrapper type for IfcSoundScaleEnum + typedef ENUMERATION IfcSoundScaleEnum; + // C++ wrapper type for IfcLuminousFluxMeasure + typedef REAL IfcLuminousFluxMeasure; + // C++ wrapper type for IfcElectricResistanceMeasure + typedef REAL IfcElectricResistanceMeasure; + // C++ wrapper type for IfcIntegerCountRateMeasure + typedef INTEGER IfcIntegerCountRateMeasure; + // C++ wrapper type for IfcPhysicalOrVirtualEnum + typedef ENUMERATION IfcPhysicalOrVirtualEnum; + // C++ wrapper type for IfcMolecularWeightMeasure + typedef REAL IfcMolecularWeightMeasure; // C++ wrapper type for IfcProfileTypeEnum typedef ENUMERATION IfcProfileTypeEnum; + // C++ wrapper type for IfcBoxAlignment + typedef STRING IfcBoxAlignment; + // C++ wrapper type for IfcGlobalOrLocalEnum + typedef ENUMERATION IfcGlobalOrLocalEnum; + // C++ wrapper type for IfcSpecularRoughness + typedef REAL IfcSpecularRoughness; + // C++ wrapper type for IfcLampTypeEnum + typedef ENUMERATION IfcLampTypeEnum; + // C++ wrapper type for IfcPileTypeEnum + typedef ENUMERATION IfcPileTypeEnum; + // C++ wrapper type for IfcElectricCurrentMeasure + typedef REAL IfcElectricCurrentMeasure; + // C++ wrapper type for IfcFanTypeEnum + typedef ENUMERATION IfcFanTypeEnum; + // C++ wrapper type for IfcSurfaceOrFaceSurface + typedef SELECT IfcSurfaceOrFaceSurface; + // C++ wrapper type for IfcPipeFittingTypeEnum + typedef ENUMERATION IfcPipeFittingTypeEnum; + // C++ wrapper type for IfcTankTypeEnum + typedef ENUMERATION IfcTankTypeEnum; // C++ wrapper type for IfcCurveFontOrScaledCurveFontSelect typedef SELECT IfcCurveFontOrScaledCurveFontSelect; - // C++ wrapper type for IfcProjectedOrTrueLengthEnum - typedef ENUMERATION IfcProjectedOrTrueLengthEnum; - // C++ wrapper type for IfcAbsorbedDoseMeasure - typedef REAL IfcAbsorbedDoseMeasure; - // C++ wrapper type for IfcParameterValue - typedef REAL IfcParameterValue; - // C++ wrapper type for IfcPileConstructionEnum - typedef ENUMERATION IfcPileConstructionEnum; + // C++ wrapper type for IfcWindowStyleConstructionEnum + typedef ENUMERATION IfcWindowStyleConstructionEnum; + // C++ wrapper type for IfcAirTerminalBoxTypeEnum + typedef ENUMERATION IfcAirTerminalBoxTypeEnum; + // C++ wrapper type for IfcStairFlightTypeEnum + typedef ENUMERATION IfcStairFlightTypeEnum; + // C++ wrapper type for IfcLuminousIntensityMeasure + typedef REAL IfcLuminousIntensityMeasure; // C++ wrapper type for IfcMotorConnectionTypeEnum typedef ENUMERATION IfcMotorConnectionTypeEnum; - // C++ wrapper type for IfcOccupantTypeEnum - typedef ENUMERATION IfcOccupantTypeEnum; - // C++ wrapper type for IfcUnit - typedef SELECT IfcUnit; - // C++ wrapper type for IfcLinearForceMeasure - typedef REAL IfcLinearForceMeasure; - // C++ wrapper type for IfcCondenserTypeEnum - typedef ENUMERATION IfcCondenserTypeEnum; - // C++ wrapper type for IfcDescriptiveMeasure - typedef STRING IfcDescriptiveMeasure; - // C++ wrapper type for IfcMomentOfInertiaMeasure - typedef REAL IfcMomentOfInertiaMeasure; - // C++ wrapper type for IfcDoseEquivalentMeasure - typedef REAL IfcDoseEquivalentMeasure; - // C++ wrapper type for IfcOrientationSelect - typedef SELECT IfcOrientationSelect; - // C++ wrapper type for IfcLogical - typedef LOGICAL IfcLogical; - // C++ wrapper type for IfcSizeSelect - typedef SELECT IfcSizeSelect; - // C++ wrapper type for IfcEnvironmentalImpactCategoryEnum - typedef ENUMERATION IfcEnvironmentalImpactCategoryEnum; - // C++ wrapper type for IfcLogicalOperatorEnum - typedef ENUMERATION IfcLogicalOperatorEnum; - // C++ wrapper type for IfcCompressorTypeEnum - typedef ENUMERATION IfcCompressorTypeEnum; - // C++ wrapper type for IfcBenchmarkEnum - typedef ENUMERATION IfcBenchmarkEnum; - // C++ wrapper type for IfcRatioMeasure - typedef REAL IfcRatioMeasure; - // C++ wrapper type for IfcVectorOrDirection - typedef SELECT IfcVectorOrDirection; - // C++ wrapper type for IfcConstraintEnum - typedef ENUMERATION IfcConstraintEnum; - // C++ wrapper type for IfcAlarmTypeEnum - typedef ENUMERATION IfcAlarmTypeEnum; - // C++ wrapper type for IfcLuminousIntensityDistributionMeasure - typedef REAL IfcLuminousIntensityDistributionMeasure; - // C++ wrapper type for IfcArithmeticOperatorEnum - typedef ENUMERATION IfcArithmeticOperatorEnum; - // C++ wrapper type for IfcAxis2Placement - typedef SELECT IfcAxis2Placement; - // C++ wrapper type for IfcForceMeasure - typedef REAL IfcForceMeasure; - // C++ wrapper type for IfcTrimmingPreference - typedef ENUMERATION IfcTrimmingPreference; - // C++ wrapper type for IfcElectricResistanceMeasure - typedef REAL IfcElectricResistanceMeasure; - // C++ wrapper type for IfcWarpingConstantMeasure - typedef REAL IfcWarpingConstantMeasure; - // C++ wrapper type for IfcPipeSegmentTypeEnum - typedef ENUMERATION IfcPipeSegmentTypeEnum; - // C++ wrapper type for IfcConditionCriterionSelect - typedef SELECT IfcConditionCriterionSelect; - // C++ wrapper type for IfcShearModulusMeasure - typedef REAL IfcShearModulusMeasure; - // C++ wrapper type for IfcPressureMeasure - typedef REAL IfcPressureMeasure; - // C++ wrapper type for IfcDuctSilencerTypeEnum - typedef ENUMERATION IfcDuctSilencerTypeEnum; - // C++ wrapper type for IfcBoolean - typedef BOOLEAN IfcBoolean; - // C++ wrapper type for IfcSectionModulusMeasure - typedef REAL IfcSectionModulusMeasure; - // C++ wrapper type for IfcChangeActionEnum - typedef ENUMERATION IfcChangeActionEnum; + // C++ wrapper type for IfcPlaneAngleMeasure + typedef REAL IfcPlaneAngleMeasure; + // C++ wrapper type for IfcActuatorTypeEnum + typedef ENUMERATION IfcActuatorTypeEnum; + // C++ wrapper type for IfcColumnTypeEnum + typedef ENUMERATION IfcColumnTypeEnum; + // C++ wrapper type for IfcTextFontSelect + typedef SELECT IfcTextFontSelect; + // C++ wrapper type for IfcDoorPanelPositionEnum + typedef ENUMERATION IfcDoorPanelPositionEnum; // C++ wrapper type for IfcCoilTypeEnum typedef ENUMERATION IfcCoilTypeEnum; - // C++ wrapper type for IfcMassMeasure - typedef REAL IfcMassMeasure; - // C++ wrapper type for IfcStructuralCurveTypeEnum - typedef ENUMERATION IfcStructuralCurveTypeEnum; - // C++ wrapper type for IfcPermeableCoveringOperationEnum - typedef ENUMERATION IfcPermeableCoveringOperationEnum; - // C++ wrapper type for IfcMagneticFluxDensityMeasure - typedef REAL IfcMagneticFluxDensityMeasure; - // C++ wrapper type for IfcMoistureDiffusivityMeasure - typedef REAL IfcMoistureDiffusivityMeasure; + // C++ wrapper type for IfcAngularVelocityMeasure + typedef REAL IfcAngularVelocityMeasure; + // C++ wrapper type for IfcAnalysisModelTypeEnum + typedef ENUMERATION IfcAnalysisModelTypeEnum; + // C++ wrapper type for IfcLibrarySelect + typedef SELECT IfcLibrarySelect; + // C++ wrapper type for IfcForceMeasure + typedef REAL IfcForceMeasure; + // C++ wrapper type for IfcFillAreaStyleTileShapeSelect + typedef SELECT IfcFillAreaStyleTileShapeSelect; + // C++ wrapper type for IfcElectricApplianceTypeEnum + typedef ENUMERATION IfcElectricApplianceTypeEnum; + // C++ wrapper type for IfcSurfaceTextureEnum + typedef ENUMERATION IfcSurfaceTextureEnum; + // C++ wrapper type for IfcCharacterStyleSelect + typedef SELECT IfcCharacterStyleSelect; + // C++ wrapper type for IfcEnergyMeasure + typedef REAL IfcEnergyMeasure; + // C++ wrapper type for IfcReal + typedef REAL IfcReal; + // C++ wrapper type for IfcCompressorTypeEnum + typedef ENUMERATION IfcCompressorTypeEnum; + // C++ wrapper type for IfcElectricDistributionPointFunctionEnum + typedef ENUMERATION IfcElectricDistributionPointFunctionEnum; // ****************************************************************************** @@ -724,654 +724,654 @@ namespace IFC { struct IfcTypeObject; struct IfcTypeProduct; struct IfcElementType; - struct IfcFurnishingElementType; - struct IfcFurnitureType; + struct IfcDistributionElementType; + struct IfcDistributionFlowElementType; + struct IfcFlowControllerType; + struct IfcElectricTimeControlType; + struct IfcRepresentation; + struct IfcShapeModel; + struct IfcTopologyRepresentation; + struct IfcRelationship; + struct IfcRelConnects; + typedef NotImplemented IfcRelCoversSpaces; // (not currently used by Assimp) + struct IfcFlowFittingType; + struct IfcCableCarrierFittingType; + typedef NotImplemented IfcStructuralConnectionCondition; // (not currently used by Assimp) + typedef NotImplemented IfcSlippageConnectionCondition; // (not currently used by Assimp) + struct IfcEnergyConversionDeviceType; + struct IfcCoilType; struct IfcObject; - struct IfcProduct; - struct IfcGrid; + struct IfcControl; + struct IfcPerformanceHistory; struct IfcRepresentationItem; struct IfcGeometricRepresentationItem; - struct IfcOneDirectionRepeatFactor; - struct IfcTwoDirectionRepeatFactor; + struct IfcTextLiteral; + struct IfcTextLiteralWithExtent; + struct IfcProductRepresentation; + struct IfcProduct; struct IfcElement; - struct IfcElementComponent; - typedef NotImplemented IfcLocalTime; // (not currently used by Assimp) - struct IfcSpatialStructureElementType; - struct IfcControl; - struct IfcActionRequest; - typedef NotImplemented IfcTextureVertex; // (not currently used by Assimp) - typedef NotImplemented IfcPropertyDefinition; // (not currently used by Assimp) - typedef NotImplemented IfcPropertySetDefinition; // (not currently used by Assimp) - typedef NotImplemented IfcFluidFlowProperties; // (not currently used by Assimp) - typedef NotImplemented IfcDocumentInformation; // (not currently used by Assimp) - typedef NotImplemented IfcCalendarDate; // (not currently used by Assimp) - struct IfcDistributionElementType; - struct IfcDistributionFlowElementType; - struct IfcEnergyConversionDeviceType; - struct IfcCooledBeamType; - struct IfcCsgPrimitive3D; - struct IfcRectangularPyramid; - typedef NotImplemented IfcStructuralLoad; // (not currently used by Assimp) - typedef NotImplemented IfcStructuralLoadStatic; // (not currently used by Assimp) - typedef NotImplemented IfcStructuralLoadLinearForce; // (not currently used by Assimp) + struct IfcDistributionElement; + struct IfcDistributionFlowElement; + struct IfcCurve; + struct IfcBoundedCurve; + struct IfcCompositeCurve; + struct Ifc2DCompositeCurve; + typedef NotImplemented IfcBoundaryCondition; // (not currently used by Assimp) + typedef NotImplemented IfcBoundaryFaceCondition; // (not currently used by Assimp) + struct IfcCartesianTransformationOperator; + struct IfcCartesianTransformationOperator3D; + struct IfcProperty; + struct IfcSimpleProperty; + struct IfcPropertyEnumeratedValue; + typedef NotImplemented IfcPresentationLayerAssignment; // (not currently used by Assimp) + typedef NotImplemented IfcPresentationLayerWithStyle; // (not currently used by Assimp) + struct IfcBuildingElementType; + struct IfcStairFlightType; struct IfcSurface; - struct IfcBoundedSurface; - struct IfcRectangularTrimmedSurface; - typedef NotImplemented IfcPhysicalQuantity; // (not currently used by Assimp) - typedef NotImplemented IfcPhysicalSimpleQuantity; // (not currently used by Assimp) - typedef NotImplemented IfcQuantityVolume; // (not currently used by Assimp) - typedef NotImplemented IfcQuantityArea; // (not currently used by Assimp) - struct IfcGroup; - struct IfcRelationship; - typedef NotImplemented IfcRelAssigns; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssignsToActor; // (not currently used by Assimp) - struct IfcHalfSpaceSolid; - struct IfcPolygonalBoundedHalfSpace; - typedef NotImplemented IfcEnergyProperties; // (not currently used by Assimp) - struct IfcAirToAirHeatRecoveryType; - struct IfcFlowFittingType; - struct IfcPipeFittingType; - struct IfcRepresentation; - struct IfcStyleModel; - struct IfcStyledRepresentation; - typedef NotImplemented IfcRelAssignsToControl; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssignsToProjectOrder; // (not currently used by Assimp) - typedef NotImplemented IfcDimensionalExponents; // (not currently used by Assimp) + struct IfcElementarySurface; + struct IfcPlane; struct IfcBooleanResult; - typedef NotImplemented IfcSoundProperties; // (not currently used by Assimp) - struct IfcFeatureElement; - struct IfcFeatureElementSubtraction; - struct IfcOpeningElement; - struct IfcConditionCriterion; + struct IfcBooleanClippingResult; + struct IfcSolidModel; + struct IfcManifoldSolidBrep; + typedef NotImplemented IfcProfileProperties; // (not currently used by Assimp) + typedef NotImplemented IfcGeneralProfileProperties; // (not currently used by Assimp) + typedef NotImplemented IfcStructuralProfileProperties; // (not currently used by Assimp) struct IfcFlowTerminalType; - struct IfcFlowControllerType; - struct IfcSwitchingDeviceType; - struct IfcSystem; - struct IfcElectricalCircuit; - typedef NotImplemented IfcActorRole; // (not currently used by Assimp) - typedef NotImplemented IfcDateAndTime; // (not currently used by Assimp) - typedef NotImplemented IfcDraughtingCalloutRelationship; // (not currently used by Assimp) - typedef NotImplemented IfcDimensionCalloutRelationship; // (not currently used by Assimp) - typedef NotImplemented IfcDerivedUnitElement; // (not currently used by Assimp) - typedef NotImplemented IfcExternalReference; // (not currently used by Assimp) - typedef NotImplemented IfcClassificationReference; // (not currently used by Assimp) - struct IfcUnitaryEquipmentType; - typedef NotImplemented IfcProperty; // (not currently used by Assimp) - struct IfcPort; - typedef NotImplemented IfcAddress; // (not currently used by Assimp) - struct IfcPlacement; - typedef NotImplemented IfcPreDefinedItem; // (not currently used by Assimp) - typedef NotImplemented IfcPreDefinedColour; // (not currently used by Assimp) - typedef NotImplemented IfcDraughtingPreDefinedColour; // (not currently used by Assimp) - struct IfcProfileDef; - struct IfcArbitraryClosedProfileDef; - struct IfcCurve; - struct IfcConic; - struct IfcCircle; + struct IfcStackTerminalType; + struct IfcStructuralItem; + struct IfcStructuralConnection; + struct IfcStructuralCurveConnection; + struct IfcJunctionBoxType; + typedef NotImplemented IfcRelAssociates; // (not currently used by Assimp) + typedef NotImplemented IfcRelAssociatesConstraint; // (not currently used by Assimp) + struct IfcPropertyDefinition; + struct IfcPropertySetDefinition; + typedef NotImplemented IfcDoorPanelProperties; // (not currently used by Assimp) + typedef NotImplemented IfcConstraintRelationship; // (not currently used by Assimp) + typedef NotImplemented IfcSpaceThermalLoadProperties; // (not currently used by Assimp) + typedef NotImplemented IfcLibraryInformation; // (not currently used by Assimp) + struct IfcProcess; + struct IfcTask; typedef NotImplemented IfcAppliedValue; // (not currently used by Assimp) typedef NotImplemented IfcEnvironmentalImpactValue; // (not currently used by Assimp) - typedef NotImplemented IfcSimpleProperty; // (not currently used by Assimp) - typedef NotImplemented IfcPropertySingleValue; // (not currently used by Assimp) - struct IfcElementarySurface; - struct IfcPlane; - typedef NotImplemented IfcPropertyBoundedValue; // (not currently used by Assimp) - struct IfcCostSchedule; - typedef NotImplemented IfcMonetaryUnit; // (not currently used by Assimp) - typedef NotImplemented IfcConnectionGeometry; // (not currently used by Assimp) - typedef NotImplemented IfcConnectionCurveGeometry; // (not currently used by Assimp) - struct IfcRightCircularCone; - struct IfcElementAssembly; - struct IfcBuildingElement; - struct IfcMember; - typedef NotImplemented IfcPropertyDependencyRelationship; // (not currently used by Assimp) - struct IfcBuildingElementProxy; - struct IfcStructuralActivity; - struct IfcStructuralAction; - struct IfcStructuralPlanarAction; - struct IfcTopologicalRepresentationItem; - struct IfcConnectedFaceSet; - struct IfcSweptSurface; - struct IfcSurfaceOfLinearExtrusion; - struct IfcArbitraryProfileDefWithVoids; - struct IfcProcess; + struct IfcRelFillsElement; struct IfcProcedure; - typedef NotImplemented IfcCurveStyleFontPattern; // (not currently used by Assimp) - struct IfcVector; - struct IfcFaceBound; - struct IfcFaceOuterBound; - struct IfcFeatureElementAddition; - struct IfcNamedUnit; - struct IfcConversionBasedUnit; - typedef NotImplemented IfcStructuralLoadSingleForce; // (not currently used by Assimp) - struct IfcHeatExchangerType; - struct IfcPresentationStyleAssignment; - struct IfcFlowTreatmentDeviceType; - struct IfcFilterType; + typedef NotImplemented IfcStructuralLoad; // (not currently used by Assimp) + typedef NotImplemented IfcStructuralLoadStatic; // (not currently used by Assimp) + typedef NotImplemented IfcStructuralLoadSingleDisplacement; // (not currently used by Assimp) + struct IfcProxy; + typedef NotImplemented IfcCurveStyleFont; // (not currently used by Assimp) struct IfcResource; - struct IfcEvaporativeCoolerType; - typedef NotImplemented IfcTextureCoordinate; // (not currently used by Assimp) - typedef NotImplemented IfcTextureCoordinateGenerator; // (not currently used by Assimp) - struct IfcOffsetCurve2D; + struct IfcConstructionResource; + struct IfcSubContractResource; + typedef NotImplemented IfcCalendarDate; // (not currently used by Assimp) + typedef NotImplemented IfcDocumentElectronicFormat; // (not currently used by Assimp) + struct IfcRelContainedInSpatialStructure; + typedef NotImplemented IfcMaterialProperties; // (not currently used by Assimp) + typedef NotImplemented IfcProductsOfCombustionProperties; // (not currently used by Assimp) + struct IfcTopologicalRepresentationItem; struct IfcEdge; - struct IfcSubedge; - struct IfcProxy; - struct IfcLine; - struct IfcColumn; - typedef NotImplemented IfcClassificationNotationFacet; // (not currently used by Assimp) + struct IfcEdgeCurve; + struct IfcPlateType; struct IfcObjectPlacement; struct IfcGridPlacement; - struct IfcDistributionControlElementType; - typedef NotImplemented IfcStructuralLoadSingleForceWarping; // (not currently used by Assimp) - typedef NotImplemented IfcExternallyDefinedTextFont; // (not currently used by Assimp) - struct IfcRelConnects; + struct IfcFireSuppressionTerminalType; + typedef NotImplemented IfcMechanicalMaterialProperties; // (not currently used by Assimp) + struct IfcFlowStorageDevice; + typedef NotImplemented IfcPerson; // (not currently used by Assimp) + struct IfcSweptSurface; + struct IfcSurfaceOfRevolution; + struct IfcOrientedEdge; + typedef NotImplemented IfcOwnerHistory; // (not currently used by Assimp) + typedef NotImplemented IfcRelAssigns; // (not currently used by Assimp) + typedef NotImplemented IfcRelAssignsToActor; // (not currently used by Assimp) + struct IfcDirection; + typedef NotImplemented IfcReinforcementBarProperties; // (not currently used by Assimp) + struct IfcProfileDef; + struct IfcParameterizedProfileDef; + struct IfcCShapeProfileDef; + struct IfcFeatureElement; + struct IfcFeatureElementSubtraction; + struct IfcEdgeFeature; + struct IfcChamferEdgeFeature; + struct IfcBuildingElement; + struct IfcColumn; + struct IfcPropertyReferenceValue; + typedef NotImplemented IfcMaterialClassificationRelationship; // (not currently used by Assimp) + struct IfcElectricMotorType; + struct IfcSpatialStructureElementType; + struct IfcSpaceType; + typedef NotImplemented IfcExternalReference; // (not currently used by Assimp) + typedef NotImplemented IfcExternallyDefinedHatchStyle; // (not currently used by Assimp) + struct IfcColumnType; + struct IfcCraneRailAShapeProfileDef; + struct IfcCondenserType; typedef NotImplemented IfcRelConnectsElements; // (not currently used by Assimp) typedef NotImplemented IfcRelConnectsWithRealizingElements; // (not currently used by Assimp) - typedef NotImplemented IfcConstraintClassificationRelationship; // (not currently used by Assimp) - struct IfcAnnotation; - struct IfcPlate; - struct IfcSolidModel; - struct IfcManifoldSolidBrep; - typedef NotImplemented IfcPreDefinedCurveFont; // (not currently used by Assimp) - typedef NotImplemented IfcBoundaryCondition; // (not currently used by Assimp) - typedef NotImplemented IfcBoundaryFaceCondition; // (not currently used by Assimp) - struct IfcFlowStorageDeviceType; - struct IfcStructuralItem; - struct IfcStructuralMember; - struct IfcStructuralCurveMember; - struct IfcStructuralConnection; - struct IfcStructuralSurfaceConnection; - struct IfcCoilType; - struct IfcDuctFittingType; - struct IfcStyledItem; - struct IfcAnnotationOccurrence; - struct IfcAnnotationCurveOccurrence; - struct IfcDimensionCurve; - struct IfcBoundedCurve; - struct IfcAxis1Placement; - typedef NotImplemented IfcLightIntensityDistribution; // (not currently used by Assimp) - typedef NotImplemented IfcPreDefinedSymbol; // (not currently used by Assimp) - struct IfcStructuralPointAction; - struct IfcSpatialStructureElement; - struct IfcSpace; - struct IfcContextDependentUnit; - typedef NotImplemented IfcVirtualGridIntersection; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssociates; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssociatesClassification; // (not currently used by Assimp) - struct IfcCoolingTowerType; - typedef NotImplemented IfcMaterialProperties; // (not currently used by Assimp) - typedef NotImplemented IfcGeneralMaterialProperties; // (not currently used by Assimp) - struct IfcFacetedBrepWithVoids; - typedef NotImplemented IfcProfileProperties; // (not currently used by Assimp) - typedef NotImplemented IfcGeneralProfileProperties; // (not currently used by Assimp) - typedef NotImplemented IfcStructuralProfileProperties; // (not currently used by Assimp) - struct IfcValveType; - struct IfcSystemFurnitureElementType; - struct IfcDiscreteAccessory; - typedef NotImplemented IfcPerson; // (not currently used by Assimp) - struct IfcBuildingElementType; - struct IfcRailingType; - struct IfcGasTerminalType; - typedef NotImplemented IfcTimeSeries; // (not currently used by Assimp) - typedef NotImplemented IfcIrregularTimeSeries; // (not currently used by Assimp) - struct IfcSpaceProgram; - struct IfcCovering; - typedef NotImplemented IfcShapeAspect; // (not currently used by Assimp) + struct IfcCircleProfileDef; + struct IfcCircleHollowProfileDef; + typedef NotImplemented IfcOrganizationRelationship; // (not currently used by Assimp) + struct IfcPlacement; + struct IfcAxis2Placement3D; struct IfcPresentationStyle; - typedef NotImplemented IfcClassificationItemRelationship; // (not currently used by Assimp) - struct IfcElectricHeaterType; - struct IfcBuildingStorey; - struct IfcVertex; - struct IfcVertexPoint; + typedef NotImplemented IfcCurveStyle; // (not currently used by Assimp) + struct IfcEquipmentElement; + struct IfcCompositeCurveSegment; + struct IfcRectangleProfileDef; + typedef NotImplemented IfcPhysicalQuantity; // (not currently used by Assimp) + typedef NotImplemented IfcPhysicalComplexQuantity; // (not currently used by Assimp) + typedef NotImplemented IfcRelAssociatesLibrary; // (not currently used by Assimp) + typedef NotImplemented IfcRelSequence; // (not currently used by Assimp) + struct IfcBuildingElementProxy; + struct IfcDistributionControlElementType; struct IfcFlowInstrumentType; - struct IfcParameterizedProfileDef; - struct IfcUShapeProfileDef; - struct IfcRamp; - typedef NotImplemented IfcFillAreaStyle; // (not currently used by Assimp) - struct IfcCompositeCurve; - typedef NotImplemented IfcRelServicesBuildings; // (not currently used by Assimp) - struct IfcStructuralCurveMemberVarying; - typedef NotImplemented IfcRelReferencedInSpatialStructure; // (not currently used by Assimp) - struct IfcRampFlightType; struct IfcDraughtingCallout; struct IfcDimensionCurveDirectedCallout; - struct IfcRadiusDimension; - struct IfcEdgeFeature; - struct IfcSweptAreaSolid; - struct IfcExtrudedAreaSolid; - typedef NotImplemented IfcQuantityCount; // (not currently used by Assimp) - struct IfcAnnotationTextOccurrence; - typedef NotImplemented IfcReferencesValueDocument; // (not currently used by Assimp) - struct IfcStair; - typedef NotImplemented IfcSymbolStyle; // (not currently used by Assimp) - struct IfcFillAreaStyleTileSymbolWithStyle; - struct IfcAnnotationSymbolOccurrence; - struct IfcTerminatorSymbol; - struct IfcDimensionCurveTerminator; - struct IfcRectangleProfileDef; - struct IfcRectangleHollowProfileDef; - typedef NotImplemented IfcRelAssociatesLibrary; // (not currently used by Assimp) - struct IfcLocalPlacement; - typedef NotImplemented IfcOpticalMaterialProperties; // (not currently used by Assimp) - typedef NotImplemented IfcServiceLifeFactor; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssignsTasks; // (not currently used by Assimp) - struct IfcTask; - struct IfcAnnotationFillAreaOccurrence; - struct IfcFace; - struct IfcFlowSegmentType; - struct IfcDuctSegmentType; - typedef NotImplemented IfcPropertyEnumeration; // (not currently used by Assimp) - struct IfcConstructionResource; - struct IfcConstructionEquipmentResource; - struct IfcSanitaryTerminalType; - typedef NotImplemented IfcPreDefinedDimensionSymbol; // (not currently used by Assimp) - typedef NotImplemented IfcOrganization; // (not currently used by Assimp) - struct IfcCircleProfileDef; - struct IfcStructuralReaction; - struct IfcStructuralPointReaction; - struct IfcRailing; - struct IfcTextLiteral; - struct IfcCartesianTransformationOperator; - typedef NotImplemented IfcCostValue; // (not currently used by Assimp) - typedef NotImplemented IfcTextStyle; // (not currently used by Assimp) struct IfcLinearDimension; - struct IfcDamperType; - struct IfcSIUnit; - typedef NotImplemented IfcSurfaceStyleLighting; // (not currently used by Assimp) - struct IfcMeasureWithUnit; - typedef NotImplemented IfcMaterialLayerSet; // (not currently used by Assimp) - struct IfcDistributionElement; - struct IfcDistributionControlElement; - struct IfcTransformerType; - struct IfcLaborResource; - struct IfcDerivedProfileDef; - typedef NotImplemented IfcRelConnectsStructuralMember; // (not currently used by Assimp) - typedef NotImplemented IfcRelConnectsWithEccentricity; // (not currently used by Assimp) - struct IfcFurnitureStandard; - struct IfcStairFlightType; - struct IfcWorkControl; - struct IfcWorkPlan; - typedef NotImplemented IfcRelDefines; // (not currently used by Assimp) - typedef NotImplemented IfcRelDefinesByProperties; // (not currently used by Assimp) - struct IfcCondition; - typedef NotImplemented IfcGridAxis; // (not currently used by Assimp) - struct IfcRelVoidsElement; - struct IfcWindow; - typedef NotImplemented IfcRelFlowControlElements; // (not currently used by Assimp) - typedef NotImplemented IfcRelConnectsPortToElement; // (not currently used by Assimp) - struct IfcProtectiveDeviceType; - struct IfcJunctionBoxType; - struct IfcStructuralAnalysisModel; - struct IfcAxis2Placement2D; - struct IfcSpaceType; - struct IfcEllipseProfileDef; - struct IfcDistributionFlowElement; - struct IfcFlowMovingDevice; - struct IfcSurfaceStyleWithTextures; - struct IfcGeometricSet; - typedef NotImplemented IfcMechanicalMaterialProperties; // (not currently used by Assimp) - typedef NotImplemented IfcMechanicalConcreteMaterialProperties; // (not currently used by Assimp) - typedef NotImplemented IfcRibPlateProfileProperties; // (not currently used by Assimp) - typedef NotImplemented IfcDocumentInformationRelationship; // (not currently used by Assimp) + struct IfcElementAssembly; + typedef NotImplemented IfcDraughtingCalloutRelationship; // (not currently used by Assimp) + struct IfcCsgPrimitive3D; + struct IfcRightCircularCone; + typedef NotImplemented IfcExternallyDefinedSurfaceStyle; // (not currently used by Assimp) struct IfcProjectOrder; - struct IfcBSplineCurve; - struct IfcBezierCurve; - struct IfcStructuralPointConnection; - struct IfcFlowController; - struct IfcElectricDistributionPoint; - struct IfcSite; + typedef NotImplemented IfcPropertyConstraintRelationship; // (not currently used by Assimp) + struct IfcLShapeProfileDef; + struct IfcAngularDimension; + typedef NotImplemented IfcTextStyleForDefinedFont; // (not currently used by Assimp) + struct IfcLocalPlacement; + struct IfcSweptAreaSolid; + struct IfcRevolvedAreaSolid; + struct IfcStructuralSurfaceConnection; + struct IfcRadiusDimension; + struct IfcSweptDiskSolid; + struct IfcHalfSpaceSolid; + struct IfcPolygonalBoundedHalfSpace; + struct IfcTimeSeriesSchedule; + typedef NotImplemented IfcDimensionCalloutRelationship; // (not currently used by Assimp) + struct IfcCooledBeamType; + struct IfcProject; + typedef NotImplemented IfcApprovalRelationship; // (not currently used by Assimp) + struct IfcEvaporatorType; + struct IfcLaborResource; + typedef NotImplemented IfcStructuralLoadSingleDisplacementDistortion; // (not currently used by Assimp) + struct IfcPropertyBoundedValue; + struct IfcRampFlightType; + struct IfcMember; + typedef NotImplemented IfcStructuralLoadPlanarForce; // (not currently used by Assimp) + struct IfcTubeBundleType; + struct IfcValveType; + typedef NotImplemented IfcExternallyDefinedTextFont; // (not currently used by Assimp) + struct IfcTrimmedCurve; + struct IfcRelDefines; + struct IfcRelDefinesByProperties; + typedef NotImplemented IfcRelAssignsToControl; // (not currently used by Assimp) + struct IfcActor; + struct IfcOccupant; + struct IfcHumidifierType; + struct IfcArbitraryOpenProfileDef; + typedef NotImplemented IfcRelAssignsToProjectOrder; // (not currently used by Assimp) + struct IfcPermit; struct IfcOffsetCurve3D; - typedef NotImplemented IfcPropertySet; // (not currently used by Assimp) - typedef NotImplemented IfcConnectionSurfaceGeometry; // (not currently used by Assimp) + struct IfcLightSource; + struct IfcLightSourcePositional; + typedef NotImplemented IfcSurfaceTexture; // (not currently used by Assimp) + typedef NotImplemented IfcBlobTexture; // (not currently used by Assimp) + struct IfcCompositeProfileDef; + typedef NotImplemented IfcDocumentInformation; // (not currently used by Assimp) + typedef NotImplemented IfcSurfaceStyleLighting; // (not currently used by Assimp) + typedef NotImplemented IfcPhysicalSimpleQuantity; // (not currently used by Assimp) + typedef NotImplemented IfcQuantityArea; // (not currently used by Assimp) + typedef NotImplemented IfcTimeSeries; // (not currently used by Assimp) + typedef NotImplemented IfcClassificationNotation; // (not currently used by Assimp) + struct IfcRamp; + typedef NotImplemented IfcPreDefinedItem; // (not currently used by Assimp) + typedef NotImplemented IfcPreDefinedCurveFont; // (not currently used by Assimp) + typedef NotImplemented IfcPreDefinedColour; // (not currently used by Assimp) + typedef NotImplemented IfcCurrencyRelationship; // (not currently used by Assimp) + struct IfcFlowMovingDevice; + struct IfcSpaceHeaterType; + struct IfcLampType; + struct IfcBuildingElementComponent; + struct IfcReinforcingElement; + struct IfcReinforcingBar; + struct IfcElectricHeaterType; + struct IfcTShapeProfileDef; + typedef NotImplemented IfcConstraint; // (not currently used by Assimp) + typedef NotImplemented IfcObjective; // (not currently used by Assimp) + struct IfcStructuralActivity; + struct IfcStructuralAction; + typedef NotImplemented IfcTextureCoordinate; // (not currently used by Assimp) + typedef NotImplemented IfcTextureMap; // (not currently used by Assimp) + typedef NotImplemented IfcMonetaryUnit; // (not currently used by Assimp) + typedef NotImplemented IfcQuantityTime; // (not currently used by Assimp) + typedef NotImplemented IfcTableRow; // (not currently used by Assimp) + typedef NotImplemented IfcLightDistributionData; // (not currently used by Assimp) + struct IfcDuctFittingType; + struct IfcCartesianTransformationOperator2D; + struct IfcCartesianTransformationOperator2DnonUniform; + typedef NotImplemented IfcClassificationNotationFacet; // (not currently used by Assimp) + typedef NotImplemented IfcRelAssociatesApproval; // (not currently used by Assimp) + typedef NotImplemented IfcDraughtingPreDefinedCurveFont; // (not currently used by Assimp) + typedef NotImplemented IfcStructuralLoadSingleForce; // (not currently used by Assimp) + typedef NotImplemented IfcStructuralLoadSingleForceWarping; // (not currently used by Assimp) + typedef NotImplemented IfcCurveStyleFontAndScaling; // (not currently used by Assimp) struct IfcVirtualElement; - struct IfcConstructionProductResource; - typedef NotImplemented IfcWaterProperties; // (not currently used by Assimp) - struct IfcSurfaceCurveSweptAreaSolid; - typedef NotImplemented IfcPermeableCoveringProperties; // (not currently used by Assimp) - struct IfcCartesianTransformationOperator3D; - struct IfcCartesianTransformationOperator3DnonUniform; - struct IfcCrewResource; - struct IfcStructuralSurfaceMember; - struct Ifc2DCompositeCurve; - struct IfcRepresentationContext; - struct IfcGeometricRepresentationContext; - struct IfcFlowTreatmentDevice; - typedef NotImplemented IfcTextStyleForDefinedFont; // (not currently used by Assimp) struct IfcRightCircularCylinder; - struct IfcWasteTerminalType; - typedef NotImplemented IfcSpaceThermalLoadProperties; // (not currently used by Assimp) - typedef NotImplemented IfcConstraintRelationship; // (not currently used by Assimp) - struct IfcBuildingElementComponent; - struct IfcBuildingElementPart; - struct IfcWall; - struct IfcWallStandardCase; - typedef NotImplemented IfcApprovalActorRelationship; // (not currently used by Assimp) + struct IfcOutletType; + struct IfcRelDecomposes; + typedef NotImplemented IfcRelNests; // (not currently used by Assimp) + struct IfcCovering; + typedef NotImplemented IfcExternallyDefinedSymbol; // (not currently used by Assimp) + typedef NotImplemented IfcIrregularTimeSeries; // (not currently used by Assimp) + struct IfcPolyline; struct IfcPath; - struct IfcDefinedSymbol; - struct IfcStructuralSurfaceMemberVarying; - struct IfcPoint; - struct IfcSurfaceOfRevolution; - struct IfcFlowTerminal; - struct IfcFurnishingElement; - typedef NotImplemented IfcCurveStyleFont; // (not currently used by Assimp) - struct IfcSurfaceStyleShading; - struct IfcSurfaceStyleRendering; - typedef NotImplemented IfcCoordinatedUniversalTimeOffset; // (not currently used by Assimp) - typedef NotImplemented IfcStructuralLoadSingleDisplacement; // (not currently used by Assimp) - struct IfcCircleHollowProfileDef; + struct IfcElementComponent; + struct IfcFastener; + struct IfcMappedItem; + typedef NotImplemented IfcMetric; // (not currently used by Assimp) + typedef NotImplemented IfcDocumentReference; // (not currently used by Assimp) + typedef NotImplemented IfcSectionProperties; // (not currently used by Assimp) + struct IfcRectangularPyramid; + typedef NotImplemented IfcRelReferencedInSpatialStructure; // (not currently used by Assimp) + struct IfcCrewResource; + struct IfcNamedUnit; + struct IfcContextDependentUnit; + struct IfcUnitaryEquipmentType; + struct IfcRoof; + typedef NotImplemented IfcRelAssignsTasks; // (not currently used by Assimp) + struct IfcStructuralMember; + typedef NotImplemented IfcRelConnectsPorts; // (not currently used by Assimp) + struct IfcStyleModel; + struct IfcStyledRepresentation; + struct IfcSpatialStructureElement; + struct IfcBuilding; + struct IfcConnectedFaceSet; + struct IfcOpenShell; + struct IfcFacetedBrep; + typedef NotImplemented IfcLocalTime; // (not currently used by Assimp) + typedef NotImplemented IfcMechanicalConcreteMaterialProperties; // (not currently used by Assimp) + struct IfcConic; + struct IfcCoveringType; + struct IfcRoundedRectangleProfileDef; + struct IfcAirTerminalType; struct IfcFlowMovingDeviceType; - struct IfcFanType; - struct IfcStructuralPlanarActionVarying; - struct IfcProductRepresentation; - typedef NotImplemented IfcRelDefinesByType; // (not currently used by Assimp) + struct IfcCompressorType; + typedef NotImplemented IfcWindowPanelProperties; // (not currently used by Assimp) + typedef NotImplemented IfcPreDefinedSymbol; // (not currently used by Assimp) + typedef NotImplemented IfcPreDefinedTerminatorSymbol; // (not currently used by Assimp) + struct IfcIShapeProfileDef; + struct IfcAsymmetricIShapeProfileDef; + struct IfcControllerType; + struct IfcRailing; + struct IfcGroup; + struct IfcAsset; + struct IfcMaterialDefinitionRepresentation; + typedef NotImplemented IfcCurveStyleFontPattern; // (not currently used by Assimp) + typedef NotImplemented IfcApprovalPropertyRelationship; // (not currently used by Assimp) + struct IfcRailingType; + struct IfcWall; + typedef NotImplemented IfcClassificationItem; // (not currently used by Assimp) + struct IfcStructuralPointConnection; + typedef NotImplemented IfcConnectionGeometry; // (not currently used by Assimp) + typedef NotImplemented IfcConnectionPointGeometry; // (not currently used by Assimp) + typedef NotImplemented IfcTimeSeriesValue; // (not currently used by Assimp) + struct IfcPropertyListValue; + struct IfcFurnitureStandard; + typedef NotImplemented IfcRelSchedulesCostItems; // (not currently used by Assimp) + struct IfcElectricGeneratorType; + struct IfcDoor; + struct IfcStyledItem; + struct IfcAnnotationOccurrence; + struct IfcAnnotationSymbolOccurrence; + struct IfcArbitraryClosedProfileDef; + struct IfcArbitraryProfileDefWithVoids; + struct IfcLine; + typedef NotImplemented IfcMaterialLayerSet; // (not currently used by Assimp) + struct IfcFlowSegmentType; + struct IfcAirTerminalBoxType; + typedef NotImplemented IfcRelConnectsStructuralMember; // (not currently used by Assimp) + struct IfcPropertySingleValue; + struct IfcAlarmType; + struct IfcEllipseProfileDef; + struct IfcStair; typedef NotImplemented IfcPreDefinedTextFont; // (not currently used by Assimp) typedef NotImplemented IfcTextStyleFontModel; // (not currently used by Assimp) - struct IfcStackTerminalType; - typedef NotImplemented IfcApprovalPropertyRelationship; // (not currently used by Assimp) - typedef NotImplemented IfcExternallyDefinedSymbol; // (not currently used by Assimp) - struct IfcReinforcingElement; - struct IfcReinforcingMesh; - struct IfcOrderAction; - typedef NotImplemented IfcRelCoversBldgElements; // (not currently used by Assimp) - struct IfcLightSource; - struct IfcLightSourceDirectional; - struct IfcLoop; - struct IfcVertexLoop; - struct IfcChamferEdgeFeature; - typedef NotImplemented IfcWindowPanelProperties; // (not currently used by Assimp) - typedef NotImplemented IfcClassification; // (not currently used by Assimp) + struct IfcSurfaceStyleShading; + struct IfcPumpType; + struct IfcDefinedSymbol; + typedef NotImplemented IfcClassificationItemRelationship; // (not currently used by Assimp) + typedef NotImplemented IfcGeneralMaterialProperties; // (not currently used by Assimp) struct IfcElementComponentType; struct IfcFastenerType; struct IfcMechanicalFastenerType; - struct IfcScheduleTimeControl; - struct IfcSurfaceStyle; - typedef NotImplemented IfcReinforcementBarProperties; // (not currently used by Assimp) - struct IfcOpenShell; - typedef NotImplemented IfcLibraryReference; // (not currently used by Assimp) - struct IfcSubContractResource; - typedef NotImplemented IfcTimeSeriesReferenceRelationship; // (not currently used by Assimp) - struct IfcSweptDiskSolid; - struct IfcCompositeProfileDef; - typedef NotImplemented IfcElectricalBaseProperties; // (not currently used by Assimp) - typedef NotImplemented IfcPreDefinedPointMarkerSymbol; // (not currently used by Assimp) - struct IfcTankType; - typedef NotImplemented IfcBoundaryNodeCondition; // (not currently used by Assimp) - typedef NotImplemented IfcBoundaryNodeConditionWarping; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssignsToGroup; // (not currently used by Assimp) - typedef NotImplemented IfcPresentationLayerAssignment; // (not currently used by Assimp) - struct IfcSphere; - struct IfcPolyLoop; - struct IfcCableCarrierFittingType; - struct IfcHumidifierType; - typedef NotImplemented IfcPropertyListValue; // (not currently used by Assimp) - typedef NotImplemented IfcPropertyConstraintRelationship; // (not currently used by Assimp) - struct IfcPerformanceHistory; - struct IfcShapeModel; - struct IfcTopologyRepresentation; - struct IfcBuilding; - struct IfcRoundedRectangleProfileDef; - struct IfcStairFlight; - typedef NotImplemented IfcSurfaceStyleRefraction; // (not currently used by Assimp) - typedef NotImplemented IfcRelInteractionRequirements; // (not currently used by Assimp) - typedef NotImplemented IfcConstraint; // (not currently used by Assimp) - typedef NotImplemented IfcObjective; // (not currently used by Assimp) - typedef NotImplemented IfcConnectionPortGeometry; // (not currently used by Assimp) - struct IfcDistributionChamberElement; - typedef NotImplemented IfcPersonAndOrganization; // (not currently used by Assimp) - struct IfcShapeRepresentation; - struct IfcRampFlight; - struct IfcBeamType; - struct IfcRelDecomposes; - struct IfcRoof; - struct IfcFooting; - typedef NotImplemented IfcRelCoversSpaces; // (not currently used by Assimp) - struct IfcLightSourceAmbient; - typedef NotImplemented IfcTimeSeriesValue; // (not currently used by Assimp) - struct IfcWindowStyle; - typedef NotImplemented IfcPropertyReferenceValue; // (not currently used by Assimp) + typedef NotImplemented IfcPermeableCoveringProperties; // (not currently used by Assimp) + struct IfcFlowFitting; typedef NotImplemented IfcApproval; // (not currently used by Assimp) - typedef NotImplemented IfcRelConnectsStructuralElement; // (not currently used by Assimp) - struct IfcBuildingElementProxyType; + typedef NotImplemented IfcShapeAspect; // (not currently used by Assimp) + typedef NotImplemented IfcConstraintClassificationRelationship; // (not currently used by Assimp) + struct IfcLightSourceDirectional; + struct IfcSurfaceStyle; + typedef NotImplemented IfcRelConnectsStructuralActivity; // (not currently used by Assimp) typedef NotImplemented IfcRelAssociatesProfileProperties; // (not currently used by Assimp) - struct IfcAxis2Placement3D; - typedef NotImplemented IfcRelConnectsPorts; // (not currently used by Assimp) - struct IfcEdgeCurve; - struct IfcClosedShell; - struct IfcTendonAnchor; - struct IfcCondenserType; - typedef NotImplemented IfcQuantityTime; // (not currently used by Assimp) - typedef NotImplemented IfcSurfaceTexture; // (not currently used by Assimp) - typedef NotImplemented IfcPixelTexture; // (not currently used by Assimp) - typedef NotImplemented IfcStructuralConnectionCondition; // (not currently used by Assimp) + struct IfcAnnotationSurface; + typedef NotImplemented IfcFuelProperties; // (not currently used by Assimp) + struct IfcFlowController; typedef NotImplemented IfcFailureConnectionCondition; // (not currently used by Assimp) - typedef NotImplemented IfcDocumentReference; // (not currently used by Assimp) - typedef NotImplemented IfcMechanicalSteelMaterialProperties; // (not currently used by Assimp) - struct IfcPipeSegmentType; - struct IfcPointOnSurface; + struct IfcBuildingStorey; + struct IfcWorkControl; + struct IfcWorkSchedule; typedef NotImplemented IfcTable; // (not currently used by Assimp) - typedef NotImplemented IfcLightDistributionData; // (not currently used by Assimp) - typedef NotImplemented IfcPropertyTableValue; // (not currently used by Assimp) - typedef NotImplemented IfcPresentationLayerWithStyle; // (not currently used by Assimp) - struct IfcAsset; - struct IfcLightSourcePositional; - typedef NotImplemented IfcLibraryInformation; // (not currently used by Assimp) - typedef NotImplemented IfcTextStyleTextModel; // (not currently used by Assimp) - struct IfcProjectionCurve; - struct IfcFillAreaStyleTiles; - struct IfcRelFillsElement; - struct IfcElectricMotorType; - struct IfcTendon; + struct IfcDuctSegmentType; + typedef NotImplemented IfcStructuralSteelProfileProperties; // (not currently used by Assimp) + typedef NotImplemented IfcDraughtingPreDefinedTextFont; // (not currently used by Assimp) + struct IfcFace; + struct IfcStructuralSurfaceMember; + struct IfcStructuralSurfaceMemberVarying; + struct IfcFaceSurface; + typedef NotImplemented IfcClassification; // (not currently used by Assimp) + typedef NotImplemented IfcMaterialList; // (not currently used by Assimp) + struct IfcCostSchedule; + typedef NotImplemented IfcCoordinatedUniversalTimeOffset; // (not currently used by Assimp) + struct IfcPlanarExtent; + struct IfcPlanarBox; + typedef NotImplemented IfcFillAreaStyle; // (not currently used by Assimp) + typedef NotImplemented IfcSectionReinforcementProperties; // (not currently used by Assimp) + struct IfcColourSpecification; + struct IfcVector; + struct IfcBeam; + struct IfcColourRgb; + struct IfcStructuralPlanarAction; + struct IfcStructuralPlanarActionVarying; + struct IfcSite; + struct IfcDiscreteAccessoryType; + struct IfcVibrationIsolatorType; + struct IfcEvaporativeCoolerType; struct IfcDistributionChamberElementType; + struct IfcFeatureElementAddition; + typedef NotImplemented IfcRelAssignsToResource; // (not currently used by Assimp) + struct IfcStructuredDimensionCallout; + struct IfcCoolingTowerType; + struct IfcCenterLineProfileDef; + typedef NotImplemented IfcTextureVertex; // (not currently used by Assimp) + typedef NotImplemented IfcOrganization; // (not currently used by Assimp) + struct IfcWindowStyle; + struct IfcLightSourceGoniometric; + typedef NotImplemented IfcRibPlateProfileProperties; // (not currently used by Assimp) + struct IfcTransformerType; struct IfcMemberType; - struct IfcStructuralLinearAction; - struct IfcStructuralLinearActionVarying; - struct IfcProductDefinitionShape; - struct IfcFastener; - struct IfcMechanicalFastener; - typedef NotImplemented IfcFuelProperties; // (not currently used by Assimp) - struct IfcEvaporatorType; - typedef NotImplemented IfcMaterialLayerSetUsage; // (not currently used by Assimp) - struct IfcDiscreteAccessoryType; - struct IfcStructuralCurveConnection; - struct IfcProjectionElement; - typedef NotImplemented IfcImageTexture; // (not currently used by Assimp) - struct IfcCoveringType; - typedef NotImplemented IfcRelAssociatesAppliedValue; // (not currently used by Assimp) - struct IfcPumpType; - struct IfcPile; - struct IfcUnitAssignment; - struct IfcBoundingBox; + struct IfcSurfaceOfLinearExtrusion; + struct IfcMotorConnectionType; + struct IfcFlowTreatmentDeviceType; + struct IfcDuctSilencerType; + typedef NotImplemented IfcWindowLiningProperties; // (not currently used by Assimp) + struct IfcFurnishingElementType; + struct IfcSystemFurnitureElementType; + typedef NotImplemented IfcConnectionPointEccentricity; // (not currently used by Assimp) + struct IfcWasteTerminalType; + struct IfcBSplineCurve; + struct IfcBezierCurve; + typedef NotImplemented IfcDocumentInformationRelationship; // (not currently used by Assimp) + struct IfcActuatorType; + struct IfcDistributionControlElement; + struct IfcAnnotation; + typedef NotImplemented IfcRelAssociatesDocument; // (not currently used by Assimp) + typedef NotImplemented IfcDoorLiningProperties; // (not currently used by Assimp) struct IfcShellBasedSurfaceModel; - struct IfcFacetedBrep; - struct IfcTextLiteralWithExtent; - typedef NotImplemented IfcApplication; // (not currently used by Assimp) - typedef NotImplemented IfcExtendedMaterialProperties; // (not currently used by Assimp) - struct IfcElectricApplianceType; - typedef NotImplemented IfcRelOccupiesSpaces; // (not currently used by Assimp) - struct IfcTrapeziumProfileDef; - typedef NotImplemented IfcQuantityWeight; // (not currently used by Assimp) - struct IfcRelContainedInSpatialStructure; - struct IfcEdgeLoop; - struct IfcProject; - struct IfcCartesianPoint; - typedef NotImplemented IfcMaterial; // (not currently used by Assimp) - struct IfcCurveBoundedPlane; - struct IfcWallType; + struct IfcActionRequest; + struct IfcExtrudedAreaSolid; + struct IfcSystem; struct IfcFillAreaStyleHatching; + struct IfcRelVoidsElement; + typedef NotImplemented IfcRelConnectsPathElements; // (not currently used by Assimp) + typedef NotImplemented IfcRelSpaceBoundary; // (not currently used by Assimp) + struct IfcSurfaceCurveSweptAreaSolid; + struct IfcCartesianTransformationOperator3DnonUniform; + typedef NotImplemented IfcRelInteractionRequirements; // (not currently used by Assimp) + struct IfcCurtainWallType; + typedef NotImplemented IfcQuantityLength; // (not currently used by Assimp) struct IfcEquipmentStandard; - typedef NotImplemented IfcHygroscopicMaterialProperties; // (not currently used by Assimp) - typedef NotImplemented IfcDoorPanelProperties; // (not currently used by Assimp) + struct IfcFlowStorageDeviceType; + typedef NotImplemented IfcVirtualGridIntersection; // (not currently used by Assimp) struct IfcDiameterDimension; - struct IfcStructuralLoadGroup; + struct IfcSwitchingDeviceType; + typedef NotImplemented IfcAddress; // (not currently used by Assimp) typedef NotImplemented IfcTelecomAddress; // (not currently used by Assimp) - struct IfcConstructionMaterialResource; - typedef NotImplemented IfcBlobTexture; // (not currently used by Assimp) - typedef NotImplemented IfcIrregularTimeSeriesValue; // (not currently used by Assimp) - struct IfcRelAggregates; - struct IfcBoilerType; + struct IfcWindow; + typedef NotImplemented IfcMechanicalSteelMaterialProperties; // (not currently used by Assimp) + struct IfcFlowTreatmentDevice; + typedef NotImplemented IfcRelServicesBuildings; // (not currently used by Assimp) + struct IfcChillerType; + typedef NotImplemented IfcRelAssignsToProduct; // (not currently used by Assimp) + struct IfcRectangleHollowProfileDef; + typedef NotImplemented IfcEnergyProperties; // (not currently used by Assimp) + struct IfcBoxedHalfSpace; + struct IfcAxis2Placement2D; + struct IfcSpaceProgram; + struct IfcPoint; + struct IfcCartesianPoint; + struct IfcBoundedSurface; + struct IfcLoop; + struct IfcPolyLoop; + typedef NotImplemented IfcPreDefinedPointMarkerSymbol; // (not currently used by Assimp) + struct IfcTerminatorSymbol; + struct IfcDimensionCurveTerminator; typedef NotImplemented IfcRelProjectsElement; // (not currently used by Assimp) - struct IfcColourSpecification; - struct IfcColourRgb; - typedef NotImplemented IfcRelConnectsStructuralActivity; // (not currently used by Assimp) - struct IfcDoorStyle; - typedef NotImplemented IfcStructuralLoadSingleDisplacementDistortion; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssignsToProcess; // (not currently used by Assimp) - struct IfcDuctSilencerType; - struct IfcLightSourceGoniometric; - struct IfcActuatorType; + struct IfcTrapeziumProfileDef; + struct IfcRepresentationContext; + struct IfcGeometricRepresentationContext; + typedef NotImplemented IfcTextStyleWithBoxCharacteristics; // (not currently used by Assimp) + struct IfcCurveBoundedPlane; + typedef NotImplemented IfcQuantityCount; // (not currently used by Assimp) + typedef NotImplemented IfcTimeSeriesReferenceRelationship; // (not currently used by Assimp) + typedef NotImplemented IfcStructuralLoadTemperature; // (not currently used by Assimp) + struct IfcSIUnit; + struct IfcStructuralReaction; + struct IfcStructuralPointReaction; + struct IfcAxis1Placement; + typedef NotImplemented IfcReinforcementDefinitionProperties; // (not currently used by Assimp) + struct IfcElectricApplianceType; struct IfcSensorType; - struct IfcAirTerminalBoxType; - struct IfcAnnotationSurfaceOccurrence; + struct IfcFurnishingElement; + struct IfcProtectiveDeviceType; struct IfcZShapeProfileDef; - typedef NotImplemented IfcClassificationNotation; // (not currently used by Assimp) - struct IfcRationalBezierCurve; - struct IfcCartesianTransformationOperator2D; - struct IfcCartesianTransformationOperator2DnonUniform; - struct IfcMove; - typedef NotImplemented IfcBoundaryEdgeCondition; // (not currently used by Assimp) - typedef NotImplemented IfcDoorLiningProperties; // (not currently used by Assimp) - struct IfcCableCarrierSegmentType; + struct IfcScheduleTimeControl; + struct IfcRepresentationMap; + struct IfcClosedShell; + struct IfcBuildingElementPart; + typedef NotImplemented IfcDraughtingPreDefinedColour; // (not currently used by Assimp) typedef NotImplemented IfcPostalAddress; // (not currently used by Assimp) - typedef NotImplemented IfcRelConnectsPathElements; // (not currently used by Assimp) - struct IfcElectricalElement; - typedef NotImplemented IfcOwnerHistory; // (not currently used by Assimp) - typedef NotImplemented IfcStructuralLoadTemperature; // (not currently used by Assimp) - typedef NotImplemented IfcTextStyleWithBoxCharacteristics; // (not currently used by Assimp) - struct IfcChillerType; - typedef NotImplemented IfcRelSchedulesCostItems; // (not currently used by Assimp) - struct IfcReinforcingBar; - typedef NotImplemented IfcCurrencyRelationship; // (not currently used by Assimp) - typedef NotImplemented IfcSoundValue; // (not currently used by Assimp) - struct IfcCShapeProfileDef; - struct IfcPermit; - struct IfcSlabType; - typedef NotImplemented IfcSlippageConnectionCondition; // (not currently used by Assimp) - struct IfcLampType; - struct IfcPlanarExtent; - struct IfcAlarmType; - typedef NotImplemented IfcDocumentElectronicFormat; // (not currently used by Assimp) - struct IfcElectricFlowStorageDeviceType; - struct IfcEquipmentElement; + struct IfcBlock; struct IfcLightFixtureType; - typedef NotImplemented IfcMetric; // (not currently used by Assimp) - typedef NotImplemented IfcRelNests; // (not currently used by Assimp) - struct IfcCurtainWall; - typedef NotImplemented IfcRelAssociatesDocument; // (not currently used by Assimp) - typedef NotImplemented IfcComplexProperty; // (not currently used by Assimp) - typedef NotImplemented IfcVertexBasedTextureMap; // (not currently used by Assimp) - struct IfcSlab; - struct IfcCurtainWallType; - struct IfcOutletType; - struct IfcCompressorType; - struct IfcCraneRailAShapeProfileDef; - struct IfcFlowSegment; - struct IfcSectionedSpine; - typedef NotImplemented IfcTableRow; // (not currently used by Assimp) - typedef NotImplemented IfcDraughtingPreDefinedTextFont; // (not currently used by Assimp) - struct IfcElectricTimeControlType; - struct IfcFaceSurface; - typedef NotImplemented IfcMaterialList; // (not currently used by Assimp) - struct IfcMotorConnectionType; - struct IfcFlowFitting; - struct IfcPointOnCurve; - struct IfcTransportElementType; - typedef NotImplemented IfcRegularTimeSeries; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssociatesConstraint; // (not currently used by Assimp) - typedef NotImplemented IfcPropertyEnumeratedValue; // (not currently used by Assimp) - typedef NotImplemented IfcStructuralSteelProfileProperties; // (not currently used by Assimp) + struct IfcOpeningElement; + struct IfcLightSourceSpot; + struct IfcTendonAnchor; + typedef NotImplemented IfcSurfaceStyleRefraction; // (not currently used by Assimp) + struct IfcElectricFlowStorageDeviceType; + typedef NotImplemented IfcFluidFlowProperties; // (not currently used by Assimp) + struct IfcSphere; + typedef NotImplemented IfcRelAssociatesAppliedValue; // (not currently used by Assimp) + struct IfcDamperType; + struct IfcProjectOrderRecord; + typedef NotImplemented IfcDimensionalExponents; // (not currently used by Assimp) + typedef NotImplemented IfcRelDefinesByType; // (not currently used by Assimp) + struct IfcDistributionChamberElement; + struct IfcMechanicalFastener; + typedef NotImplemented IfcQuantityVolume; // (not currently used by Assimp) + struct IfcRectangularTrimmedSurface; + typedef NotImplemented IfcDateAndTime; // (not currently used by Assimp) + struct IfcZone; + struct IfcFanType; + struct IfcGeometricSet; + struct IfcFillAreaStyleTiles; + typedef NotImplemented IfcPixelTexture; // (not currently used by Assimp) struct IfcCableSegmentType; - typedef NotImplemented IfcExternallyDefinedHatchStyle; // (not currently used by Assimp) - struct IfcAnnotationSurface; - struct IfcCompositeCurveSegment; + struct IfcRelOverridesProperties; + struct IfcMeasureWithUnit; + struct IfcSlabType; struct IfcServiceLife; - struct IfcPlateType; - typedef NotImplemented IfcCurveStyle; // (not currently used by Assimp) - typedef NotImplemented IfcSectionProperties; // (not currently used by Assimp) - struct IfcVibrationIsolatorType; - typedef NotImplemented IfcTextureMap; // (not currently used by Assimp) - struct IfcTrimmedCurve; - struct IfcMappedItem; - typedef NotImplemented IfcMaterialLayer; // (not currently used by Assimp) - struct IfcDirection; - struct IfcBlock; - struct IfcProjectOrderRecord; - struct IfcFlowMeterType; - struct IfcControllerType; - struct IfcBeam; - struct IfcArbitraryOpenProfileDef; - struct IfcCenterLineProfileDef; - typedef NotImplemented IfcStructuralLoadPlanarForce; // (not currently used by Assimp) - struct IfcTimeSeriesSchedule; - struct IfcRoundedEdgeFeature; - typedef NotImplemented IfcWindowLiningProperties; // (not currently used by Assimp) - typedef NotImplemented IfcRelOverridesProperties; // (not currently used by Assimp) - typedef NotImplemented IfcApprovalRelationship; // (not currently used by Assimp) - struct IfcIShapeProfileDef; - struct IfcSpaceHeaterType; - typedef NotImplemented IfcExternallyDefinedSurfaceStyle; // (not currently used by Assimp) - typedef NotImplemented IfcDerivedUnit; // (not currently used by Assimp) - struct IfcFlowStorageDevice; - typedef NotImplemented IfcMaterialClassificationRelationship; // (not currently used by Assimp) - typedef NotImplemented IfcClassificationItem; // (not currently used by Assimp) - struct IfcRevolvedAreaSolid; - typedef NotImplemented IfcConnectionPointGeometry; // (not currently used by Assimp) - struct IfcDoor; - struct IfcEllipse; - struct IfcTubeBundleType; - struct IfcAngularDimension; - typedef NotImplemented IfcThermalMaterialProperties; // (not currently used by Assimp) + struct IfcFurnitureType; + struct IfcCostItem; + struct IfcReinforcingMesh; + typedef NotImplemented IfcExtendedMaterialProperties; // (not currently used by Assimp) + typedef NotImplemented IfcActorRole; // (not currently used by Assimp) + struct IfcFacetedBrepWithVoids; + typedef NotImplemented IfcConstraintAggregationRelationship; // (not currently used by Assimp) + struct IfcGasTerminalType; + typedef NotImplemented IfcRelConnectsWithEccentricity; // (not currently used by Assimp) + struct IfcPile; + struct IfcFillAreaStyleTileSymbolWithStyle; + typedef NotImplemented IfcElectricalBaseProperties; // (not currently used by Assimp) + struct IfcConstructionMaterialResource; + struct IfcAnnotationCurveOccurrence; + struct IfcDimensionCurve; + struct IfcGeometricCurveSet; + struct IfcRelAggregates; struct IfcFaceBasedSurfaceModel; - struct IfcCraneRailFShapeProfileDef; - struct IfcColumnType; - struct IfcTShapeProfileDef; struct IfcEnergyConversionDevice; - typedef NotImplemented IfcConnectionPointEccentricity; // (not currently used by Assimp) - typedef NotImplemented IfcReinforcementDefinitionProperties; // (not currently used by Assimp) - typedef NotImplemented IfcCurveStyleFontAndScaling; // (not currently used by Assimp) - struct IfcWorkSchedule; - typedef NotImplemented IfcOrganizationRelationship; // (not currently used by Assimp) - struct IfcZone; - struct IfcTransportElement; - typedef NotImplemented IfcDraughtingPreDefinedCurveFont; // (not currently used by Assimp) - struct IfcGeometricRepresentationSubContext; - struct IfcLShapeProfileDef; - struct IfcGeometricCurveSet; - struct IfcActor; - struct IfcOccupant; - typedef NotImplemented IfcPhysicalComplexQuantity; // (not currently used by Assimp) - struct IfcBooleanClippingResult; - typedef NotImplemented IfcPreDefinedTerminatorSymbol; // (not currently used by Assimp) - struct IfcAnnotationFillArea; - typedef NotImplemented IfcConstraintAggregationRelationship; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssociatesApproval; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssociatesMaterial; // (not currently used by Assimp) - typedef NotImplemented IfcRelAssignsToProduct; // (not currently used by Assimp) - typedef NotImplemented IfcAppliedValueRelationship; // (not currently used by Assimp) - struct IfcLightSourceSpot; - struct IfcFireSuppressionTerminalType; - typedef NotImplemented IfcElementQuantity; // (not currently used by Assimp) + struct IfcRampFlight; + typedef NotImplemented IfcPropertyEnumeration; // (not currently used by Assimp) + struct IfcVertexLoop; + struct IfcPlate; + struct IfcUShapeProfileDef; + typedef NotImplemented IfcHygroscopicMaterialProperties; // (not currently used by Assimp) + struct IfcFaceBound; + struct IfcFaceOuterBound; + struct IfcOneDirectionRepeatFactor; + struct IfcBoilerType; + struct IfcConstructionEquipmentResource; + struct IfcComplexProperty; + struct IfcFooting; + typedef NotImplemented IfcOpticalMaterialProperties; // (not currently used by Assimp) + struct IfcConstructionProductResource; + typedef NotImplemented IfcBoundaryEdgeCondition; // (not currently used by Assimp) + struct IfcDerivedProfileDef; + struct IfcPropertyTableValue; + typedef NotImplemented IfcRelAssignsToGroup; // (not currently used by Assimp) + struct IfcFlowMeterType; + struct IfcDoorStyle; + typedef NotImplemented IfcRelConnectsPortToElement; // (not currently used by Assimp) + typedef NotImplemented IfcRelAssociatesClassification; // (not currently used by Assimp) + struct IfcUnitAssignment; + struct IfcFlowTerminal; + struct IfcCraneRailFShapeProfileDef; + struct IfcFlowSegment; + struct IfcElementQuantity; + typedef NotImplemented IfcBoundaryNodeCondition; // (not currently used by Assimp) + typedef NotImplemented IfcBoundaryNodeConditionWarping; // (not currently used by Assimp) + struct IfcCurtainWall; + struct IfcDiscreteAccessory; + struct IfcGrid; + struct IfcSanitaryTerminalType; + typedef NotImplemented IfcSoundProperties; // (not currently used by Assimp) + struct IfcSubedge; + typedef NotImplemented IfcTextStyleTextModel; // (not currently used by Assimp) + struct IfcFilterType; + typedef NotImplemented IfcSymbolStyle; // (not currently used by Assimp) + struct IfcTendon; typedef NotImplemented IfcDimensionPair; // (not currently used by Assimp) - struct IfcElectricGeneratorType; - typedef NotImplemented IfcRelSequence; // (not currently used by Assimp) + struct IfcStructuralLoadGroup; + struct IfcPresentationStyleAssignment; + typedef NotImplemented IfcRegularTimeSeries; // (not currently used by Assimp) + struct IfcStructuralCurveMember; + struct IfcLightSourceAmbient; + struct IfcCondition; + struct IfcPort; + struct IfcSpace; + struct IfcHeatExchangerType; + struct IfcTankType; struct IfcInventory; - struct IfcPolyline; - struct IfcBoxedHalfSpace; - struct IfcAirTerminalType; - typedef NotImplemented IfcSectionReinforcementProperties; // (not currently used by Assimp) - struct IfcDistributionPort; - struct IfcCostItem; - struct IfcStructuredDimensionCallout; + typedef NotImplemented IfcTextStyle; // (not currently used by Assimp) + typedef NotImplemented IfcAppliedValueRelationship; // (not currently used by Assimp) + typedef NotImplemented IfcSoundValue; // (not currently used by Assimp) + struct IfcTransportElementType; + struct IfcAirToAirHeatRecoveryType; + struct IfcStairFlight; + struct IfcElectricalElement; + typedef NotImplemented IfcLightIntensityDistribution; // (not currently used by Assimp) + typedef NotImplemented IfcClassificationReference; // (not currently used by Assimp) + struct IfcSurfaceStyleWithTextures; + struct IfcBoundingBox; + typedef NotImplemented IfcApplication; // (not currently used by Assimp) + struct IfcWallType; + struct IfcMove; + struct IfcCircle; + struct IfcOffsetCurve2D; + typedef NotImplemented IfcMaterialLayerSetUsage; // (not currently used by Assimp) + struct IfcPointOnCurve; struct IfcStructuralResultGroup; - typedef NotImplemented IfcRelSpaceBoundary; // (not currently used by Assimp) - struct IfcOrientedEdge; - typedef NotImplemented IfcRelAssignsToResource; // (not currently used by Assimp) + struct IfcSectionedSpine; + struct IfcSlab; + typedef NotImplemented IfcConnectionPortGeometry; // (not currently used by Assimp) + typedef NotImplemented IfcQuantityWeight; // (not currently used by Assimp) + typedef NotImplemented IfcRelAssociatesMaterial; // (not currently used by Assimp) + struct IfcVertex; + struct IfcVertexPoint; + typedef NotImplemented IfcReferencesValueDocument; // (not currently used by Assimp) + typedef NotImplemented IfcPersonAndOrganization; // (not currently used by Assimp) + typedef NotImplemented IfcRelFlowControlElements; // (not currently used by Assimp) + typedef NotImplemented IfcRelAssignsToProcess; // (not currently used by Assimp) + struct IfcStructuralLinearAction; + struct IfcStructuralLinearActionVarying; + struct IfcBuildingElementProxyType; + struct IfcProjectionElement; + typedef NotImplemented IfcDerivedUnit; // (not currently used by Assimp) + typedef NotImplemented IfcApprovalActorRelationship; // (not currently used by Assimp) + struct IfcConversionBasedUnit; + typedef NotImplemented IfcMaterial; // (not currently used by Assimp) + struct IfcGeometricRepresentationSubContext; + struct IfcAnnotationSurfaceOccurrence; + typedef NotImplemented IfcPreDefinedDimensionSymbol; // (not currently used by Assimp) + struct IfcRoundedEdgeFeature; + typedef NotImplemented IfcRelCoversBldgElements; // (not currently used by Assimp) + struct IfcElectricDistributionPoint; + struct IfcCableCarrierSegmentType; + typedef NotImplemented IfcStructuralLoadLinearForce; // (not currently used by Assimp) + typedef NotImplemented IfcGridAxis; // (not currently used by Assimp) + typedef NotImplemented IfcIrregularTimeSeriesValue; // (not currently used by Assimp) + struct IfcWallStandardCase; + typedef NotImplemented IfcRelOccupiesSpaces; // (not currently used by Assimp) + typedef NotImplemented IfcDerivedUnitElement; // (not currently used by Assimp) struct IfcCsgSolid; - typedef NotImplemented IfcProductsOfCombustionProperties; // (not currently used by Assimp) + struct IfcBeamType; + struct IfcAnnotationFillArea; typedef NotImplemented IfcRelaxation; // (not currently used by Assimp) - struct IfcPlanarBox; - typedef NotImplemented IfcQuantityLength; // (not currently used by Assimp) - struct IfcMaterialDefinitionRepresentation; - struct IfcAsymmetricIShapeProfileDef; - struct IfcRepresentationMap; + struct IfcStructuralCurveMemberVarying; + struct IfcPointOnSurface; + typedef NotImplemented IfcPropertyDependencyRelationship; // (not currently used by Assimp) + typedef NotImplemented IfcVertexBasedTextureMap; // (not currently used by Assimp) + struct IfcOrderAction; + typedef NotImplemented IfcLibraryReference; // (not currently used by Assimp) + struct IfcEdgeLoop; + struct IfcAnnotationFillAreaOccurrence; + typedef NotImplemented IfcRelConnectsStructuralElement; // (not currently used by Assimp) + struct IfcWorkPlan; + struct IfcEllipse; + struct IfcProductDefinitionShape; + struct IfcProjectionCurve; + struct IfcElectricalCircuit; + struct IfcRationalBezierCurve; + struct IfcStructuralPointAction; + typedef NotImplemented IfcServiceLifeFactor; // (not currently used by Assimp) + typedef NotImplemented IfcThermalMaterialProperties; // (not currently used by Assimp) + typedef NotImplemented IfcTextureCoordinateGenerator; // (not currently used by Assimp) + struct IfcPipeSegmentType; + struct IfcTwoDirectionRepeatFactor; + struct IfcShapeRepresentation; + struct IfcPropertySet; + struct IfcSurfaceStyleRendering; + struct IfcDistributionPort; + typedef NotImplemented IfcImageTexture; // (not currently used by Assimp) + struct IfcPipeFittingType; + struct IfcTransportElement; + struct IfcAnnotationTextOccurrence; + typedef NotImplemented IfcConnectionSurfaceGeometry; // (not currently used by Assimp) + struct IfcStructuralAnalysisModel; + typedef NotImplemented IfcConnectionCurveGeometry; // (not currently used by Assimp) + struct IfcConditionCriterion; + typedef NotImplemented IfcWaterProperties; // (not currently used by Assimp) + typedef NotImplemented IfcMaterialLayer; // (not currently used by Assimp) + typedef NotImplemented IfcCostValue; // (not currently used by Assimp) @@ -1391,7 +1391,7 @@ namespace IFC { // C++ wrapper for IfcTypeObject struct IfcTypeObject : IfcObjectDefinition, ObjectHelper<IfcTypeObject,2> { IfcTypeObject() : Object("IfcTypeObject") {} Maybe< IfcLabel::Out > ApplicableOccurrence; - Maybe< ListOf< Lazy< NotImplemented >, 1, 0 > > HasPropertySets; + Maybe< ListOf< Lazy< IfcPropertySetDefinition >, 1, 0 > > HasPropertySets; }; // C++ wrapper for IfcTypeProduct @@ -1405,67 +1405,77 @@ namespace IFC { Maybe< IfcLabel::Out > ElementType; }; - // C++ wrapper for IfcFurnishingElementType - struct IfcFurnishingElementType : IfcElementType, ObjectHelper<IfcFurnishingElementType,0> { IfcFurnishingElementType() : Object("IfcFurnishingElementType") {} + // C++ wrapper for IfcDistributionElementType + struct IfcDistributionElementType : IfcElementType, ObjectHelper<IfcDistributionElementType,0> { IfcDistributionElementType() : Object("IfcDistributionElementType") {} }; - // C++ wrapper for IfcFurnitureType - struct IfcFurnitureType : IfcFurnishingElementType, ObjectHelper<IfcFurnitureType,1> { IfcFurnitureType() : Object("IfcFurnitureType") {} - IfcAssemblyPlaceEnum::Out AssemblyPlace; + // C++ wrapper for IfcDistributionFlowElementType + struct IfcDistributionFlowElementType : IfcDistributionElementType, ObjectHelper<IfcDistributionFlowElementType,0> { IfcDistributionFlowElementType() : Object("IfcDistributionFlowElementType") {} + }; - // C++ wrapper for IfcObject - struct IfcObject : IfcObjectDefinition, ObjectHelper<IfcObject,1> { IfcObject() : Object("IfcObject") {} - Maybe< IfcLabel::Out > ObjectType; + // C++ wrapper for IfcFlowControllerType + struct IfcFlowControllerType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowControllerType,0> { IfcFlowControllerType() : Object("IfcFlowControllerType") {} + }; - // C++ wrapper for IfcProduct - struct IfcProduct : IfcObject, ObjectHelper<IfcProduct,2> { IfcProduct() : Object("IfcProduct") {} - Maybe< Lazy< IfcObjectPlacement > > ObjectPlacement; - Maybe< Lazy< IfcProductRepresentation > > Representation; + // C++ wrapper for IfcElectricTimeControlType + struct IfcElectricTimeControlType : IfcFlowControllerType, ObjectHelper<IfcElectricTimeControlType,1> { IfcElectricTimeControlType() : Object("IfcElectricTimeControlType") {} + IfcElectricTimeControlTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcGrid - struct IfcGrid : IfcProduct, ObjectHelper<IfcGrid,3> { IfcGrid() : Object("IfcGrid") {} - ListOf< Lazy< NotImplemented >, 1, 0 > UAxes; - ListOf< Lazy< NotImplemented >, 1, 0 > VAxes; - Maybe< ListOf< Lazy< NotImplemented >, 1, 0 > > WAxes; + // C++ wrapper for IfcRepresentation + struct IfcRepresentation : ObjectHelper<IfcRepresentation,4> { IfcRepresentation() : Object("IfcRepresentation") {} + Lazy< IfcRepresentationContext > ContextOfItems; + Maybe< IfcLabel::Out > RepresentationIdentifier; + Maybe< IfcLabel::Out > RepresentationType; + ListOf< Lazy< IfcRepresentationItem >, 1, 0 > Items; }; - // C++ wrapper for IfcRepresentationItem - struct IfcRepresentationItem : ObjectHelper<IfcRepresentationItem,0> { IfcRepresentationItem() : Object("IfcRepresentationItem") {} + // C++ wrapper for IfcShapeModel + struct IfcShapeModel : IfcRepresentation, ObjectHelper<IfcShapeModel,0> { IfcShapeModel() : Object("IfcShapeModel") {} }; - // C++ wrapper for IfcGeometricRepresentationItem - struct IfcGeometricRepresentationItem : IfcRepresentationItem, ObjectHelper<IfcGeometricRepresentationItem,0> { IfcGeometricRepresentationItem() : Object("IfcGeometricRepresentationItem") {} + // C++ wrapper for IfcTopologyRepresentation + struct IfcTopologyRepresentation : IfcShapeModel, ObjectHelper<IfcTopologyRepresentation,0> { IfcTopologyRepresentation() : Object("IfcTopologyRepresentation") {} }; - // C++ wrapper for IfcOneDirectionRepeatFactor - struct IfcOneDirectionRepeatFactor : IfcGeometricRepresentationItem, ObjectHelper<IfcOneDirectionRepeatFactor,1> { IfcOneDirectionRepeatFactor() : Object("IfcOneDirectionRepeatFactor") {} - Lazy< IfcVector > RepeatFactor; + // C++ wrapper for IfcRelationship + struct IfcRelationship : IfcRoot, ObjectHelper<IfcRelationship,0> { IfcRelationship() : Object("IfcRelationship") {} + }; - // C++ wrapper for IfcTwoDirectionRepeatFactor - struct IfcTwoDirectionRepeatFactor : IfcOneDirectionRepeatFactor, ObjectHelper<IfcTwoDirectionRepeatFactor,1> { IfcTwoDirectionRepeatFactor() : Object("IfcTwoDirectionRepeatFactor") {} - Lazy< IfcVector > SecondRepeatFactor; + // C++ wrapper for IfcRelConnects + struct IfcRelConnects : IfcRelationship, ObjectHelper<IfcRelConnects,0> { IfcRelConnects() : Object("IfcRelConnects") {} + }; - // C++ wrapper for IfcElement - struct IfcElement : IfcProduct, ObjectHelper<IfcElement,1> { IfcElement() : Object("IfcElement") {} - Maybe< IfcIdentifier::Out > Tag; + // C++ wrapper for IfcFlowFittingType + struct IfcFlowFittingType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowFittingType,0> { IfcFlowFittingType() : Object("IfcFlowFittingType") {} + }; - // C++ wrapper for IfcElementComponent - struct IfcElementComponent : IfcElement, ObjectHelper<IfcElementComponent,0> { IfcElementComponent() : Object("IfcElementComponent") {} + // C++ wrapper for IfcCableCarrierFittingType + struct IfcCableCarrierFittingType : IfcFlowFittingType, ObjectHelper<IfcCableCarrierFittingType,1> { IfcCableCarrierFittingType() : Object("IfcCableCarrierFittingType") {} + IfcCableCarrierFittingTypeEnum::Out PredefinedType; + }; + + // C++ wrapper for IfcEnergyConversionDeviceType + struct IfcEnergyConversionDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcEnergyConversionDeviceType,0> { IfcEnergyConversionDeviceType() : Object("IfcEnergyConversionDeviceType") {} }; - // C++ wrapper for IfcSpatialStructureElementType - struct IfcSpatialStructureElementType : IfcElementType, ObjectHelper<IfcSpatialStructureElementType,0> { IfcSpatialStructureElementType() : Object("IfcSpatialStructureElementType") {} + // C++ wrapper for IfcCoilType + struct IfcCoilType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCoilType,1> { IfcCoilType() : Object("IfcCoilType") {} + IfcCoilTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcObject + struct IfcObject : IfcObjectDefinition, ObjectHelper<IfcObject,1> { IfcObject() : Object("IfcObject") {} + Maybe< IfcLabel::Out > ObjectType; }; // C++ wrapper for IfcControl @@ -1473,116 +1483,135 @@ namespace IFC { }; - // C++ wrapper for IfcActionRequest - struct IfcActionRequest : IfcControl, ObjectHelper<IfcActionRequest,1> { IfcActionRequest() : Object("IfcActionRequest") {} - IfcIdentifier::Out RequestID; + // C++ wrapper for IfcPerformanceHistory + struct IfcPerformanceHistory : IfcControl, ObjectHelper<IfcPerformanceHistory,1> { IfcPerformanceHistory() : Object("IfcPerformanceHistory") {} + IfcLabel::Out LifeCyclePhase; }; - // C++ wrapper for IfcDistributionElementType - struct IfcDistributionElementType : IfcElementType, ObjectHelper<IfcDistributionElementType,0> { IfcDistributionElementType() : Object("IfcDistributionElementType") {} + // C++ wrapper for IfcRepresentationItem + struct IfcRepresentationItem : ObjectHelper<IfcRepresentationItem,0> { IfcRepresentationItem() : Object("IfcRepresentationItem") {} }; - // C++ wrapper for IfcDistributionFlowElementType - struct IfcDistributionFlowElementType : IfcDistributionElementType, ObjectHelper<IfcDistributionFlowElementType,0> { IfcDistributionFlowElementType() : Object("IfcDistributionFlowElementType") {} + // C++ wrapper for IfcGeometricRepresentationItem + struct IfcGeometricRepresentationItem : IfcRepresentationItem, ObjectHelper<IfcGeometricRepresentationItem,0> { IfcGeometricRepresentationItem() : Object("IfcGeometricRepresentationItem") {} }; - // C++ wrapper for IfcEnergyConversionDeviceType - struct IfcEnergyConversionDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcEnergyConversionDeviceType,0> { IfcEnergyConversionDeviceType() : Object("IfcEnergyConversionDeviceType") {} + // C++ wrapper for IfcTextLiteral + struct IfcTextLiteral : IfcGeometricRepresentationItem, ObjectHelper<IfcTextLiteral,3> { IfcTextLiteral() : Object("IfcTextLiteral") {} + IfcPresentableText::Out Literal; + IfcAxis2Placement::Out Placement; + IfcTextPath::Out Path; + }; + // C++ wrapper for IfcTextLiteralWithExtent + struct IfcTextLiteralWithExtent : IfcTextLiteral, ObjectHelper<IfcTextLiteralWithExtent,2> { IfcTextLiteralWithExtent() : Object("IfcTextLiteralWithExtent") {} + Lazy< IfcPlanarExtent > Extent; + IfcBoxAlignment::Out BoxAlignment; }; - // C++ wrapper for IfcCooledBeamType - struct IfcCooledBeamType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCooledBeamType,1> { IfcCooledBeamType() : Object("IfcCooledBeamType") {} - IfcCooledBeamTypeEnum::Out PredefinedType; + // C++ wrapper for IfcProductRepresentation + struct IfcProductRepresentation : ObjectHelper<IfcProductRepresentation,3> { IfcProductRepresentation() : Object("IfcProductRepresentation") {} + Maybe< IfcLabel::Out > Name; + Maybe< IfcText::Out > Description; + ListOf< Lazy< IfcRepresentation >, 1, 0 > Representations; }; - // C++ wrapper for IfcCsgPrimitive3D - struct IfcCsgPrimitive3D : IfcGeometricRepresentationItem, ObjectHelper<IfcCsgPrimitive3D,1> { IfcCsgPrimitive3D() : Object("IfcCsgPrimitive3D") {} - Lazy< IfcAxis2Placement3D > Position; + // C++ wrapper for IfcProduct + struct IfcProduct : IfcObject, ObjectHelper<IfcProduct,2> { IfcProduct() : Object("IfcProduct") {} + Maybe< Lazy< IfcObjectPlacement > > ObjectPlacement; + Maybe< Lazy< IfcProductRepresentation > > Representation; }; - // C++ wrapper for IfcRectangularPyramid - struct IfcRectangularPyramid : IfcCsgPrimitive3D, ObjectHelper<IfcRectangularPyramid,3> { IfcRectangularPyramid() : Object("IfcRectangularPyramid") {} - IfcPositiveLengthMeasure::Out XLength; - IfcPositiveLengthMeasure::Out YLength; - IfcPositiveLengthMeasure::Out Height; + // C++ wrapper for IfcElement + struct IfcElement : IfcProduct, ObjectHelper<IfcElement,1> { IfcElement() : Object("IfcElement") {} + Maybe< IfcIdentifier::Out > Tag; }; - // C++ wrapper for IfcSurface - struct IfcSurface : IfcGeometricRepresentationItem, ObjectHelper<IfcSurface,0> { IfcSurface() : Object("IfcSurface") {} + // C++ wrapper for IfcDistributionElement + struct IfcDistributionElement : IfcElement, ObjectHelper<IfcDistributionElement,0> { IfcDistributionElement() : Object("IfcDistributionElement") {} }; - // C++ wrapper for IfcBoundedSurface - struct IfcBoundedSurface : IfcSurface, ObjectHelper<IfcBoundedSurface,0> { IfcBoundedSurface() : Object("IfcBoundedSurface") {} + // C++ wrapper for IfcDistributionFlowElement + struct IfcDistributionFlowElement : IfcDistributionElement, ObjectHelper<IfcDistributionFlowElement,0> { IfcDistributionFlowElement() : Object("IfcDistributionFlowElement") {} }; - // C++ wrapper for IfcRectangularTrimmedSurface - struct IfcRectangularTrimmedSurface : IfcBoundedSurface, ObjectHelper<IfcRectangularTrimmedSurface,7> { IfcRectangularTrimmedSurface() : Object("IfcRectangularTrimmedSurface") {} - Lazy< IfcSurface > BasisSurface; - IfcParameterValue::Out U1; - IfcParameterValue::Out V1; - IfcParameterValue::Out U2; - IfcParameterValue::Out V2; - BOOLEAN::Out Usense; - BOOLEAN::Out Vsense; + // C++ wrapper for IfcCurve + struct IfcCurve : IfcGeometricRepresentationItem, ObjectHelper<IfcCurve,0> { IfcCurve() : Object("IfcCurve") {} + }; - // C++ wrapper for IfcGroup - struct IfcGroup : IfcObject, ObjectHelper<IfcGroup,0> { IfcGroup() : Object("IfcGroup") {} + // C++ wrapper for IfcBoundedCurve + struct IfcBoundedCurve : IfcCurve, ObjectHelper<IfcBoundedCurve,0> { IfcBoundedCurve() : Object("IfcBoundedCurve") {} }; - // C++ wrapper for IfcRelationship - struct IfcRelationship : IfcRoot, ObjectHelper<IfcRelationship,0> { IfcRelationship() : Object("IfcRelationship") {} + // C++ wrapper for IfcCompositeCurve + struct IfcCompositeCurve : IfcBoundedCurve, ObjectHelper<IfcCompositeCurve,2> { IfcCompositeCurve() : Object("IfcCompositeCurve") {} + ListOf< Lazy< IfcCompositeCurveSegment >, 1, 0 > Segments; + LOGICAL::Out SelfIntersect; + }; + + // C++ wrapper for Ifc2DCompositeCurve + struct Ifc2DCompositeCurve : IfcCompositeCurve, ObjectHelper<Ifc2DCompositeCurve,0> { Ifc2DCompositeCurve() : Object("Ifc2DCompositeCurve") {} }; - // C++ wrapper for IfcHalfSpaceSolid - struct IfcHalfSpaceSolid : IfcGeometricRepresentationItem, ObjectHelper<IfcHalfSpaceSolid,2> { IfcHalfSpaceSolid() : Object("IfcHalfSpaceSolid") {} - Lazy< IfcSurface > BaseSurface; - BOOLEAN::Out AgreementFlag; + // C++ wrapper for IfcCartesianTransformationOperator + struct IfcCartesianTransformationOperator : IfcGeometricRepresentationItem, ObjectHelper<IfcCartesianTransformationOperator,4> { IfcCartesianTransformationOperator() : Object("IfcCartesianTransformationOperator") {} + Maybe< Lazy< IfcDirection > > Axis1; + Maybe< Lazy< IfcDirection > > Axis2; + Lazy< IfcCartesianPoint > LocalOrigin; + Maybe< REAL::Out > Scale; }; - // C++ wrapper for IfcPolygonalBoundedHalfSpace - struct IfcPolygonalBoundedHalfSpace : IfcHalfSpaceSolid, ObjectHelper<IfcPolygonalBoundedHalfSpace,2> { IfcPolygonalBoundedHalfSpace() : Object("IfcPolygonalBoundedHalfSpace") {} - Lazy< IfcAxis2Placement3D > Position; - Lazy< IfcBoundedCurve > PolygonalBoundary; + // C++ wrapper for IfcCartesianTransformationOperator3D + struct IfcCartesianTransformationOperator3D : IfcCartesianTransformationOperator, ObjectHelper<IfcCartesianTransformationOperator3D,1> { IfcCartesianTransformationOperator3D() : Object("IfcCartesianTransformationOperator3D") {} + Maybe< Lazy< IfcDirection > > Axis3; }; - // C++ wrapper for IfcAirToAirHeatRecoveryType - struct IfcAirToAirHeatRecoveryType : IfcEnergyConversionDeviceType, ObjectHelper<IfcAirToAirHeatRecoveryType,1> { IfcAirToAirHeatRecoveryType() : Object("IfcAirToAirHeatRecoveryType") {} - IfcAirToAirHeatRecoveryTypeEnum::Out PredefinedType; + // C++ wrapper for IfcProperty + struct IfcProperty : ObjectHelper<IfcProperty,2> { IfcProperty() : Object("IfcProperty") {} + IfcIdentifier::Out Name; + Maybe< IfcText::Out > Description; }; - // C++ wrapper for IfcFlowFittingType - struct IfcFlowFittingType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowFittingType,0> { IfcFlowFittingType() : Object("IfcFlowFittingType") {} + // C++ wrapper for IfcSimpleProperty + struct IfcSimpleProperty : IfcProperty, ObjectHelper<IfcSimpleProperty,0> { IfcSimpleProperty() : Object("IfcSimpleProperty") {} }; - // C++ wrapper for IfcPipeFittingType - struct IfcPipeFittingType : IfcFlowFittingType, ObjectHelper<IfcPipeFittingType,1> { IfcPipeFittingType() : Object("IfcPipeFittingType") {} - IfcPipeFittingTypeEnum::Out PredefinedType; + // C++ wrapper for IfcPropertyEnumeratedValue + struct IfcPropertyEnumeratedValue : IfcSimpleProperty, ObjectHelper<IfcPropertyEnumeratedValue,2> { IfcPropertyEnumeratedValue() : Object("IfcPropertyEnumeratedValue") {} + ListOf< IfcValue, 1, 0 >::Out EnumerationValues; + Maybe< Lazy< NotImplemented > > EnumerationReference; }; - // C++ wrapper for IfcRepresentation - struct IfcRepresentation : ObjectHelper<IfcRepresentation,4> { IfcRepresentation() : Object("IfcRepresentation") {} - Lazy< IfcRepresentationContext > ContextOfItems; - Maybe< IfcLabel::Out > RepresentationIdentifier; - Maybe< IfcLabel::Out > RepresentationType; - ListOf< Lazy< IfcRepresentationItem >, 1, 0 > Items; + // C++ wrapper for IfcBuildingElementType + struct IfcBuildingElementType : IfcElementType, ObjectHelper<IfcBuildingElementType,0> { IfcBuildingElementType() : Object("IfcBuildingElementType") {} + }; - // C++ wrapper for IfcStyleModel - struct IfcStyleModel : IfcRepresentation, ObjectHelper<IfcStyleModel,0> { IfcStyleModel() : Object("IfcStyleModel") {} + // C++ wrapper for IfcStairFlightType + struct IfcStairFlightType : IfcBuildingElementType, ObjectHelper<IfcStairFlightType,1> { IfcStairFlightType() : Object("IfcStairFlightType") {} + IfcStairFlightTypeEnum::Out PredefinedType; + }; + + // C++ wrapper for IfcSurface + struct IfcSurface : IfcGeometricRepresentationItem, ObjectHelper<IfcSurface,0> { IfcSurface() : Object("IfcSurface") {} }; - // C++ wrapper for IfcStyledRepresentation - struct IfcStyledRepresentation : IfcStyleModel, ObjectHelper<IfcStyledRepresentation,0> { IfcStyledRepresentation() : Object("IfcStyledRepresentation") {} + // C++ wrapper for IfcElementarySurface + struct IfcElementarySurface : IfcSurface, ObjectHelper<IfcElementarySurface,1> { IfcElementarySurface() : Object("IfcElementarySurface") {} + Lazy< IfcAxis2Placement3D > Position; + }; + + // C++ wrapper for IfcPlane + struct IfcPlane : IfcElementarySurface, ObjectHelper<IfcPlane,0> { IfcPlane() : Object("IfcPlane") {} }; @@ -1593,25 +1622,19 @@ namespace IFC { IfcBooleanOperand::Out SecondOperand; }; - // C++ wrapper for IfcFeatureElement - struct IfcFeatureElement : IfcElement, ObjectHelper<IfcFeatureElement,0> { IfcFeatureElement() : Object("IfcFeatureElement") {} - - }; - - // C++ wrapper for IfcFeatureElementSubtraction - struct IfcFeatureElementSubtraction : IfcFeatureElement, ObjectHelper<IfcFeatureElementSubtraction,0> { IfcFeatureElementSubtraction() : Object("IfcFeatureElementSubtraction") {} + // C++ wrapper for IfcBooleanClippingResult + struct IfcBooleanClippingResult : IfcBooleanResult, ObjectHelper<IfcBooleanClippingResult,0> { IfcBooleanClippingResult() : Object("IfcBooleanClippingResult") {} }; - // C++ wrapper for IfcOpeningElement - struct IfcOpeningElement : IfcFeatureElementSubtraction, ObjectHelper<IfcOpeningElement,0> { IfcOpeningElement() : Object("IfcOpeningElement") {} + // C++ wrapper for IfcSolidModel + struct IfcSolidModel : IfcGeometricRepresentationItem, ObjectHelper<IfcSolidModel,0> { IfcSolidModel() : Object("IfcSolidModel") {} }; - // C++ wrapper for IfcConditionCriterion - struct IfcConditionCriterion : IfcControl, ObjectHelper<IfcConditionCriterion,2> { IfcConditionCriterion() : Object("IfcConditionCriterion") {} - IfcConditionCriterionSelect::Out Criterion; - IfcDateTimeSelect::Out CriterionDateTime; + // C++ wrapper for IfcManifoldSolidBrep + struct IfcManifoldSolidBrep : IfcSolidModel, ObjectHelper<IfcManifoldSolidBrep,1> { IfcManifoldSolidBrep() : Object("IfcManifoldSolidBrep") {} + Lazy< IfcClosedShell > Outer; }; // C++ wrapper for IfcFlowTerminalType @@ -1619,141 +1642,140 @@ namespace IFC { }; - // C++ wrapper for IfcFlowControllerType - struct IfcFlowControllerType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowControllerType,0> { IfcFlowControllerType() : Object("IfcFlowControllerType") {} - + // C++ wrapper for IfcStackTerminalType + struct IfcStackTerminalType : IfcFlowTerminalType, ObjectHelper<IfcStackTerminalType,1> { IfcStackTerminalType() : Object("IfcStackTerminalType") {} + IfcStackTerminalTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcSwitchingDeviceType - struct IfcSwitchingDeviceType : IfcFlowControllerType, ObjectHelper<IfcSwitchingDeviceType,1> { IfcSwitchingDeviceType() : Object("IfcSwitchingDeviceType") {} - IfcSwitchingDeviceTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcStructuralItem + struct IfcStructuralItem : IfcProduct, ObjectHelper<IfcStructuralItem,0> { IfcStructuralItem() : Object("IfcStructuralItem") {} - // C++ wrapper for IfcSystem - struct IfcSystem : IfcGroup, ObjectHelper<IfcSystem,0> { IfcSystem() : Object("IfcSystem") {} + }; + // C++ wrapper for IfcStructuralConnection + struct IfcStructuralConnection : IfcStructuralItem, ObjectHelper<IfcStructuralConnection,1> { IfcStructuralConnection() : Object("IfcStructuralConnection") {} + Maybe< Lazy< NotImplemented > > AppliedCondition; }; - // C++ wrapper for IfcElectricalCircuit - struct IfcElectricalCircuit : IfcSystem, ObjectHelper<IfcElectricalCircuit,0> { IfcElectricalCircuit() : Object("IfcElectricalCircuit") {} + // C++ wrapper for IfcStructuralCurveConnection + struct IfcStructuralCurveConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralCurveConnection,0> { IfcStructuralCurveConnection() : Object("IfcStructuralCurveConnection") {} }; - // C++ wrapper for IfcUnitaryEquipmentType - struct IfcUnitaryEquipmentType : IfcEnergyConversionDeviceType, ObjectHelper<IfcUnitaryEquipmentType,1> { IfcUnitaryEquipmentType() : Object("IfcUnitaryEquipmentType") {} - IfcUnitaryEquipmentTypeEnum::Out PredefinedType; + // C++ wrapper for IfcJunctionBoxType + struct IfcJunctionBoxType : IfcFlowFittingType, ObjectHelper<IfcJunctionBoxType,1> { IfcJunctionBoxType() : Object("IfcJunctionBoxType") {} + IfcJunctionBoxTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcPort - struct IfcPort : IfcProduct, ObjectHelper<IfcPort,0> { IfcPort() : Object("IfcPort") {} + // C++ wrapper for IfcPropertyDefinition + struct IfcPropertyDefinition : IfcRoot, ObjectHelper<IfcPropertyDefinition,0> { IfcPropertyDefinition() : Object("IfcPropertyDefinition") {} }; - // C++ wrapper for IfcPlacement - struct IfcPlacement : IfcGeometricRepresentationItem, ObjectHelper<IfcPlacement,1> { IfcPlacement() : Object("IfcPlacement") {} - Lazy< IfcCartesianPoint > Location; - }; + // C++ wrapper for IfcPropertySetDefinition + struct IfcPropertySetDefinition : IfcPropertyDefinition, ObjectHelper<IfcPropertySetDefinition,0> { IfcPropertySetDefinition() : Object("IfcPropertySetDefinition") {} - // C++ wrapper for IfcProfileDef - struct IfcProfileDef : ObjectHelper<IfcProfileDef,2> { IfcProfileDef() : Object("IfcProfileDef") {} - IfcProfileTypeEnum::Out ProfileType; - Maybe< IfcLabel::Out > ProfileName; }; - // C++ wrapper for IfcArbitraryClosedProfileDef - struct IfcArbitraryClosedProfileDef : IfcProfileDef, ObjectHelper<IfcArbitraryClosedProfileDef,1> { IfcArbitraryClosedProfileDef() : Object("IfcArbitraryClosedProfileDef") {} - Lazy< IfcCurve > OuterCurve; - }; + // C++ wrapper for IfcProcess + struct IfcProcess : IfcObject, ObjectHelper<IfcProcess,0> { IfcProcess() : Object("IfcProcess") {} - // C++ wrapper for IfcCurve - struct IfcCurve : IfcGeometricRepresentationItem, ObjectHelper<IfcCurve,0> { IfcCurve() : Object("IfcCurve") {} + }; + // C++ wrapper for IfcTask + struct IfcTask : IfcProcess, ObjectHelper<IfcTask,5> { IfcTask() : Object("IfcTask") {} + IfcIdentifier::Out TaskId; + Maybe< IfcLabel::Out > Status; + Maybe< IfcLabel::Out > WorkMethod; + BOOLEAN::Out IsMilestone; + Maybe< INTEGER::Out > Priority; }; - // C++ wrapper for IfcConic - struct IfcConic : IfcCurve, ObjectHelper<IfcConic,1> { IfcConic() : Object("IfcConic") {} - IfcAxis2Placement::Out Position; + // C++ wrapper for IfcRelFillsElement + struct IfcRelFillsElement : IfcRelConnects, ObjectHelper<IfcRelFillsElement,2> { IfcRelFillsElement() : Object("IfcRelFillsElement") {} + Lazy< IfcOpeningElement > RelatingOpeningElement; + Lazy< IfcElement > RelatedBuildingElement; }; - // C++ wrapper for IfcCircle - struct IfcCircle : IfcConic, ObjectHelper<IfcCircle,1> { IfcCircle() : Object("IfcCircle") {} - IfcPositiveLengthMeasure::Out Radius; + // C++ wrapper for IfcProcedure + struct IfcProcedure : IfcProcess, ObjectHelper<IfcProcedure,3> { IfcProcedure() : Object("IfcProcedure") {} + IfcIdentifier::Out ProcedureID; + IfcProcedureTypeEnum::Out ProcedureType; + Maybe< IfcLabel::Out > UserDefinedProcedureType; }; - // C++ wrapper for IfcElementarySurface - struct IfcElementarySurface : IfcSurface, ObjectHelper<IfcElementarySurface,1> { IfcElementarySurface() : Object("IfcElementarySurface") {} - Lazy< IfcAxis2Placement3D > Position; + // C++ wrapper for IfcProxy + struct IfcProxy : IfcProduct, ObjectHelper<IfcProxy,2> { IfcProxy() : Object("IfcProxy") {} + IfcObjectTypeEnum::Out ProxyType; + Maybe< IfcLabel::Out > Tag; }; - // C++ wrapper for IfcPlane - struct IfcPlane : IfcElementarySurface, ObjectHelper<IfcPlane,0> { IfcPlane() : Object("IfcPlane") {} + // C++ wrapper for IfcResource + struct IfcResource : IfcObject, ObjectHelper<IfcResource,0> { IfcResource() : Object("IfcResource") {} }; - // C++ wrapper for IfcCostSchedule - struct IfcCostSchedule : IfcControl, ObjectHelper<IfcCostSchedule,8> { IfcCostSchedule() : Object("IfcCostSchedule") {} - Maybe< IfcActorSelect::Out > SubmittedBy; - Maybe< IfcActorSelect::Out > PreparedBy; - Maybe< IfcDateTimeSelect::Out > SubmittedOn; - Maybe< IfcLabel::Out > Status; - Maybe< ListOf< IfcActorSelect, 1, 0 >::Out > TargetUsers; - Maybe< IfcDateTimeSelect::Out > UpdateDate; - IfcIdentifier::Out ID; - IfcCostScheduleTypeEnum::Out PredefinedType; + // C++ wrapper for IfcConstructionResource + struct IfcConstructionResource : IfcResource, ObjectHelper<IfcConstructionResource,4> { IfcConstructionResource() : Object("IfcConstructionResource") {} + Maybe< IfcIdentifier::Out > ResourceIdentifier; + Maybe< IfcLabel::Out > ResourceGroup; + Maybe< IfcResourceConsumptionEnum::Out > ResourceConsumption; + Maybe< Lazy< IfcMeasureWithUnit > > BaseQuantity; }; - // C++ wrapper for IfcRightCircularCone - struct IfcRightCircularCone : IfcCsgPrimitive3D, ObjectHelper<IfcRightCircularCone,2> { IfcRightCircularCone() : Object("IfcRightCircularCone") {} - IfcPositiveLengthMeasure::Out Height; - IfcPositiveLengthMeasure::Out BottomRadius; + // C++ wrapper for IfcSubContractResource + struct IfcSubContractResource : IfcConstructionResource, ObjectHelper<IfcSubContractResource,2> { IfcSubContractResource() : Object("IfcSubContractResource") {} + Maybe< IfcActorSelect::Out > SubContractor; + Maybe< IfcText::Out > JobDescription; }; - // C++ wrapper for IfcElementAssembly - struct IfcElementAssembly : IfcElement, ObjectHelper<IfcElementAssembly,2> { IfcElementAssembly() : Object("IfcElementAssembly") {} - Maybe< IfcAssemblyPlaceEnum::Out > AssemblyPlace; - IfcElementAssemblyTypeEnum::Out PredefinedType; + // C++ wrapper for IfcRelContainedInSpatialStructure + struct IfcRelContainedInSpatialStructure : IfcRelConnects, ObjectHelper<IfcRelContainedInSpatialStructure,2> { IfcRelContainedInSpatialStructure() : Object("IfcRelContainedInSpatialStructure") {} + ListOf< Lazy< IfcProduct >, 1, 0 > RelatedElements; + Lazy< IfcSpatialStructureElement > RelatingStructure; }; - // C++ wrapper for IfcBuildingElement - struct IfcBuildingElement : IfcElement, ObjectHelper<IfcBuildingElement,0> { IfcBuildingElement() : Object("IfcBuildingElement") {} + // C++ wrapper for IfcTopologicalRepresentationItem + struct IfcTopologicalRepresentationItem : IfcRepresentationItem, ObjectHelper<IfcTopologicalRepresentationItem,0> { IfcTopologicalRepresentationItem() : Object("IfcTopologicalRepresentationItem") {} }; - // C++ wrapper for IfcMember - struct IfcMember : IfcBuildingElement, ObjectHelper<IfcMember,0> { IfcMember() : Object("IfcMember") {} - + // C++ wrapper for IfcEdge + struct IfcEdge : IfcTopologicalRepresentationItem, ObjectHelper<IfcEdge,2> { IfcEdge() : Object("IfcEdge") {} + Lazy< IfcVertex > EdgeStart; + Lazy< IfcVertex > EdgeEnd; }; - // C++ wrapper for IfcBuildingElementProxy - struct IfcBuildingElementProxy : IfcBuildingElement, ObjectHelper<IfcBuildingElementProxy,1> { IfcBuildingElementProxy() : Object("IfcBuildingElementProxy") {} - Maybe< IfcElementCompositionEnum::Out > CompositionType; + // C++ wrapper for IfcEdgeCurve + struct IfcEdgeCurve : IfcEdge, ObjectHelper<IfcEdgeCurve,2> { IfcEdgeCurve() : Object("IfcEdgeCurve") {} + Lazy< IfcCurve > EdgeGeometry; + BOOLEAN::Out SameSense; }; - // C++ wrapper for IfcStructuralActivity - struct IfcStructuralActivity : IfcProduct, ObjectHelper<IfcStructuralActivity,2> { IfcStructuralActivity() : Object("IfcStructuralActivity") {} - Lazy< NotImplemented > AppliedLoad; - IfcGlobalOrLocalEnum::Out GlobalOrLocal; + // C++ wrapper for IfcPlateType + struct IfcPlateType : IfcBuildingElementType, ObjectHelper<IfcPlateType,1> { IfcPlateType() : Object("IfcPlateType") {} + IfcPlateTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcStructuralAction - struct IfcStructuralAction : IfcStructuralActivity, ObjectHelper<IfcStructuralAction,2> { IfcStructuralAction() : Object("IfcStructuralAction") {} - BOOLEAN::Out DestabilizingLoad; - Maybe< Lazy< IfcStructuralReaction > > CausedBy; - }; + // C++ wrapper for IfcObjectPlacement + struct IfcObjectPlacement : ObjectHelper<IfcObjectPlacement,0> { IfcObjectPlacement() : Object("IfcObjectPlacement") {} - // C++ wrapper for IfcStructuralPlanarAction - struct IfcStructuralPlanarAction : IfcStructuralAction, ObjectHelper<IfcStructuralPlanarAction,1> { IfcStructuralPlanarAction() : Object("IfcStructuralPlanarAction") {} - IfcProjectedOrTrueLengthEnum::Out ProjectedOrTrue; }; - // C++ wrapper for IfcTopologicalRepresentationItem - struct IfcTopologicalRepresentationItem : IfcRepresentationItem, ObjectHelper<IfcTopologicalRepresentationItem,0> { IfcTopologicalRepresentationItem() : Object("IfcTopologicalRepresentationItem") {} + // C++ wrapper for IfcGridPlacement + struct IfcGridPlacement : IfcObjectPlacement, ObjectHelper<IfcGridPlacement,2> { IfcGridPlacement() : Object("IfcGridPlacement") {} + Lazy< NotImplemented > PlacementLocation; + Maybe< Lazy< NotImplemented > > PlacementRefDirection; + }; + // C++ wrapper for IfcFireSuppressionTerminalType + struct IfcFireSuppressionTerminalType : IfcFlowTerminalType, ObjectHelper<IfcFireSuppressionTerminalType,1> { IfcFireSuppressionTerminalType() : Object("IfcFireSuppressionTerminalType") {} + IfcFireSuppressionTerminalTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcConnectedFaceSet - struct IfcConnectedFaceSet : IfcTopologicalRepresentationItem, ObjectHelper<IfcConnectedFaceSet,1> { IfcConnectedFaceSet() : Object("IfcConnectedFaceSet") {} - ListOf< Lazy< IfcFace >, 1, 0 > CfsFaces; + // C++ wrapper for IfcFlowStorageDevice + struct IfcFlowStorageDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowStorageDevice,0> { IfcFlowStorageDevice() : Object("IfcFlowStorageDevice") {} + }; // C++ wrapper for IfcSweptSurface @@ -1762,137 +1784,168 @@ namespace IFC { Lazy< IfcAxis2Placement3D > Position; }; - // C++ wrapper for IfcSurfaceOfLinearExtrusion - struct IfcSurfaceOfLinearExtrusion : IfcSweptSurface, ObjectHelper<IfcSurfaceOfLinearExtrusion,2> { IfcSurfaceOfLinearExtrusion() : Object("IfcSurfaceOfLinearExtrusion") {} - Lazy< IfcDirection > ExtrudedDirection; - IfcLengthMeasure::Out Depth; + // C++ wrapper for IfcSurfaceOfRevolution + struct IfcSurfaceOfRevolution : IfcSweptSurface, ObjectHelper<IfcSurfaceOfRevolution,1> { IfcSurfaceOfRevolution() : Object("IfcSurfaceOfRevolution") {} + Lazy< IfcAxis1Placement > AxisPosition; }; - // C++ wrapper for IfcArbitraryProfileDefWithVoids - struct IfcArbitraryProfileDefWithVoids : IfcArbitraryClosedProfileDef, ObjectHelper<IfcArbitraryProfileDefWithVoids,1> { IfcArbitraryProfileDefWithVoids() : Object("IfcArbitraryProfileDefWithVoids") {} - ListOf< Lazy< IfcCurve >, 1, 0 > InnerCurves; + // C++ wrapper for IfcOrientedEdge + struct IfcOrientedEdge : IfcEdge, ObjectHelper<IfcOrientedEdge,2> { IfcOrientedEdge() : Object("IfcOrientedEdge") {} + Lazy< IfcEdge > EdgeElement; + BOOLEAN::Out Orientation; }; - // C++ wrapper for IfcProcess - struct IfcProcess : IfcObject, ObjectHelper<IfcProcess,0> { IfcProcess() : Object("IfcProcess") {} + // C++ wrapper for IfcDirection + struct IfcDirection : IfcGeometricRepresentationItem, ObjectHelper<IfcDirection,1> { IfcDirection() : Object("IfcDirection") {} + ListOf< REAL, 2, 3 >::Out DirectionRatios; + }; + // C++ wrapper for IfcProfileDef + struct IfcProfileDef : ObjectHelper<IfcProfileDef,2> { IfcProfileDef() : Object("IfcProfileDef") {} + IfcProfileTypeEnum::Out ProfileType; + Maybe< IfcLabel::Out > ProfileName; }; - // C++ wrapper for IfcProcedure - struct IfcProcedure : IfcProcess, ObjectHelper<IfcProcedure,3> { IfcProcedure() : Object("IfcProcedure") {} - IfcIdentifier::Out ProcedureID; - IfcProcedureTypeEnum::Out ProcedureType; - Maybe< IfcLabel::Out > UserDefinedProcedureType; + // C++ wrapper for IfcParameterizedProfileDef + struct IfcParameterizedProfileDef : IfcProfileDef, ObjectHelper<IfcParameterizedProfileDef,1> { IfcParameterizedProfileDef() : Object("IfcParameterizedProfileDef") {} + Lazy< IfcAxis2Placement2D > Position; }; - // C++ wrapper for IfcVector - struct IfcVector : IfcGeometricRepresentationItem, ObjectHelper<IfcVector,2> { IfcVector() : Object("IfcVector") {} - Lazy< IfcDirection > Orientation; - IfcLengthMeasure::Out Magnitude; + // C++ wrapper for IfcCShapeProfileDef + struct IfcCShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCShapeProfileDef,6> { IfcCShapeProfileDef() : Object("IfcCShapeProfileDef") {} + IfcPositiveLengthMeasure::Out Depth; + IfcPositiveLengthMeasure::Out Width; + IfcPositiveLengthMeasure::Out WallThickness; + IfcPositiveLengthMeasure::Out Girth; + Maybe< IfcPositiveLengthMeasure::Out > InternalFilletRadius; + Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX; }; - // C++ wrapper for IfcFaceBound - struct IfcFaceBound : IfcTopologicalRepresentationItem, ObjectHelper<IfcFaceBound,2> { IfcFaceBound() : Object("IfcFaceBound") {} - Lazy< IfcLoop > Bound; - BOOLEAN::Out Orientation; + // C++ wrapper for IfcFeatureElement + struct IfcFeatureElement : IfcElement, ObjectHelper<IfcFeatureElement,0> { IfcFeatureElement() : Object("IfcFeatureElement") {} + }; - // C++ wrapper for IfcFaceOuterBound - struct IfcFaceOuterBound : IfcFaceBound, ObjectHelper<IfcFaceOuterBound,0> { IfcFaceOuterBound() : Object("IfcFaceOuterBound") {} + // C++ wrapper for IfcFeatureElementSubtraction + struct IfcFeatureElementSubtraction : IfcFeatureElement, ObjectHelper<IfcFeatureElementSubtraction,0> { IfcFeatureElementSubtraction() : Object("IfcFeatureElementSubtraction") {} }; - // C++ wrapper for IfcFeatureElementAddition - struct IfcFeatureElementAddition : IfcFeatureElement, ObjectHelper<IfcFeatureElementAddition,0> { IfcFeatureElementAddition() : Object("IfcFeatureElementAddition") {} + // C++ wrapper for IfcEdgeFeature + struct IfcEdgeFeature : IfcFeatureElementSubtraction, ObjectHelper<IfcEdgeFeature,1> { IfcEdgeFeature() : Object("IfcEdgeFeature") {} + Maybe< IfcPositiveLengthMeasure::Out > FeatureLength; + }; + // C++ wrapper for IfcChamferEdgeFeature + struct IfcChamferEdgeFeature : IfcEdgeFeature, ObjectHelper<IfcChamferEdgeFeature,2> { IfcChamferEdgeFeature() : Object("IfcChamferEdgeFeature") {} + Maybe< IfcPositiveLengthMeasure::Out > Width; + Maybe< IfcPositiveLengthMeasure::Out > Height; }; - // C++ wrapper for IfcNamedUnit - struct IfcNamedUnit : ObjectHelper<IfcNamedUnit,2> { IfcNamedUnit() : Object("IfcNamedUnit") {} - Lazy< NotImplemented > Dimensions; - IfcUnitEnum::Out UnitType; + // C++ wrapper for IfcBuildingElement + struct IfcBuildingElement : IfcElement, ObjectHelper<IfcBuildingElement,0> { IfcBuildingElement() : Object("IfcBuildingElement") {} + }; - // C++ wrapper for IfcConversionBasedUnit - struct IfcConversionBasedUnit : IfcNamedUnit, ObjectHelper<IfcConversionBasedUnit,2> { IfcConversionBasedUnit() : Object("IfcConversionBasedUnit") {} - IfcLabel::Out Name; - Lazy< IfcMeasureWithUnit > ConversionFactor; + // C++ wrapper for IfcColumn + struct IfcColumn : IfcBuildingElement, ObjectHelper<IfcColumn,0> { IfcColumn() : Object("IfcColumn") {} + }; - // C++ wrapper for IfcHeatExchangerType - struct IfcHeatExchangerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcHeatExchangerType,1> { IfcHeatExchangerType() : Object("IfcHeatExchangerType") {} - IfcHeatExchangerTypeEnum::Out PredefinedType; + // C++ wrapper for IfcPropertyReferenceValue + struct IfcPropertyReferenceValue : IfcSimpleProperty, ObjectHelper<IfcPropertyReferenceValue,2> { IfcPropertyReferenceValue() : Object("IfcPropertyReferenceValue") {} + Maybe< IfcLabel::Out > UsageName; + IfcObjectReferenceSelect::Out PropertyReference; }; - // C++ wrapper for IfcPresentationStyleAssignment - struct IfcPresentationStyleAssignment : ObjectHelper<IfcPresentationStyleAssignment,1> { IfcPresentationStyleAssignment() : Object("IfcPresentationStyleAssignment") {} - ListOf< IfcPresentationStyleSelect, 1, 0 >::Out Styles; + // C++ wrapper for IfcElectricMotorType + struct IfcElectricMotorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcElectricMotorType,1> { IfcElectricMotorType() : Object("IfcElectricMotorType") {} + IfcElectricMotorTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcFlowTreatmentDeviceType - struct IfcFlowTreatmentDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowTreatmentDeviceType,0> { IfcFlowTreatmentDeviceType() : Object("IfcFlowTreatmentDeviceType") {} + // C++ wrapper for IfcSpatialStructureElementType + struct IfcSpatialStructureElementType : IfcElementType, ObjectHelper<IfcSpatialStructureElementType,0> { IfcSpatialStructureElementType() : Object("IfcSpatialStructureElementType") {} }; - // C++ wrapper for IfcFilterType - struct IfcFilterType : IfcFlowTreatmentDeviceType, ObjectHelper<IfcFilterType,1> { IfcFilterType() : Object("IfcFilterType") {} - IfcFilterTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSpaceType + struct IfcSpaceType : IfcSpatialStructureElementType, ObjectHelper<IfcSpaceType,1> { IfcSpaceType() : Object("IfcSpaceType") {} + IfcSpaceTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcResource - struct IfcResource : IfcObject, ObjectHelper<IfcResource,0> { IfcResource() : Object("IfcResource") {} + // C++ wrapper for IfcColumnType + struct IfcColumnType : IfcBuildingElementType, ObjectHelper<IfcColumnType,1> { IfcColumnType() : Object("IfcColumnType") {} + IfcColumnTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcCraneRailAShapeProfileDef + struct IfcCraneRailAShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCraneRailAShapeProfileDef,12> { IfcCraneRailAShapeProfileDef() : Object("IfcCraneRailAShapeProfileDef") {} + IfcPositiveLengthMeasure::Out OverallHeight; + IfcPositiveLengthMeasure::Out BaseWidth2; + Maybe< IfcPositiveLengthMeasure::Out > Radius; + IfcPositiveLengthMeasure::Out HeadWidth; + IfcPositiveLengthMeasure::Out HeadDepth2; + IfcPositiveLengthMeasure::Out HeadDepth3; + IfcPositiveLengthMeasure::Out WebThickness; + IfcPositiveLengthMeasure::Out BaseWidth4; + IfcPositiveLengthMeasure::Out BaseDepth1; + IfcPositiveLengthMeasure::Out BaseDepth2; + IfcPositiveLengthMeasure::Out BaseDepth3; + Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; }; - // C++ wrapper for IfcEvaporativeCoolerType - struct IfcEvaporativeCoolerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcEvaporativeCoolerType,1> { IfcEvaporativeCoolerType() : Object("IfcEvaporativeCoolerType") {} - IfcEvaporativeCoolerTypeEnum::Out PredefinedType; + // C++ wrapper for IfcCondenserType + struct IfcCondenserType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCondenserType,1> { IfcCondenserType() : Object("IfcCondenserType") {} + IfcCondenserTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcOffsetCurve2D - struct IfcOffsetCurve2D : IfcCurve, ObjectHelper<IfcOffsetCurve2D,3> { IfcOffsetCurve2D() : Object("IfcOffsetCurve2D") {} - Lazy< IfcCurve > BasisCurve; - IfcLengthMeasure::Out Distance; - LOGICAL::Out SelfIntersect; + // C++ wrapper for IfcCircleProfileDef + struct IfcCircleProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCircleProfileDef,1> { IfcCircleProfileDef() : Object("IfcCircleProfileDef") {} + IfcPositiveLengthMeasure::Out Radius; }; - // C++ wrapper for IfcEdge - struct IfcEdge : IfcTopologicalRepresentationItem, ObjectHelper<IfcEdge,2> { IfcEdge() : Object("IfcEdge") {} - Lazy< IfcVertex > EdgeStart; - Lazy< IfcVertex > EdgeEnd; + // C++ wrapper for IfcCircleHollowProfileDef + struct IfcCircleHollowProfileDef : IfcCircleProfileDef, ObjectHelper<IfcCircleHollowProfileDef,1> { IfcCircleHollowProfileDef() : Object("IfcCircleHollowProfileDef") {} + IfcPositiveLengthMeasure::Out WallThickness; }; - // C++ wrapper for IfcSubedge - struct IfcSubedge : IfcEdge, ObjectHelper<IfcSubedge,1> { IfcSubedge() : Object("IfcSubedge") {} - Lazy< IfcEdge > ParentEdge; + // C++ wrapper for IfcPlacement + struct IfcPlacement : IfcGeometricRepresentationItem, ObjectHelper<IfcPlacement,1> { IfcPlacement() : Object("IfcPlacement") {} + Lazy< IfcCartesianPoint > Location; }; - // C++ wrapper for IfcProxy - struct IfcProxy : IfcProduct, ObjectHelper<IfcProxy,2> { IfcProxy() : Object("IfcProxy") {} - IfcObjectTypeEnum::Out ProxyType; - Maybe< IfcLabel::Out > Tag; + // C++ wrapper for IfcAxis2Placement3D + struct IfcAxis2Placement3D : IfcPlacement, ObjectHelper<IfcAxis2Placement3D,2> { IfcAxis2Placement3D() : Object("IfcAxis2Placement3D") {} + Maybe< Lazy< IfcDirection > > Axis; + Maybe< Lazy< IfcDirection > > RefDirection; }; - // C++ wrapper for IfcLine - struct IfcLine : IfcCurve, ObjectHelper<IfcLine,2> { IfcLine() : Object("IfcLine") {} - Lazy< IfcCartesianPoint > Pnt; - Lazy< IfcVector > Dir; + // C++ wrapper for IfcPresentationStyle + struct IfcPresentationStyle : ObjectHelper<IfcPresentationStyle,1> { IfcPresentationStyle() : Object("IfcPresentationStyle") {} + Maybe< IfcLabel::Out > Name; }; - // C++ wrapper for IfcColumn - struct IfcColumn : IfcBuildingElement, ObjectHelper<IfcColumn,0> { IfcColumn() : Object("IfcColumn") {} + // C++ wrapper for IfcEquipmentElement + struct IfcEquipmentElement : IfcElement, ObjectHelper<IfcEquipmentElement,0> { IfcEquipmentElement() : Object("IfcEquipmentElement") {} }; - // C++ wrapper for IfcObjectPlacement - struct IfcObjectPlacement : ObjectHelper<IfcObjectPlacement,0> { IfcObjectPlacement() : Object("IfcObjectPlacement") {} + // C++ wrapper for IfcCompositeCurveSegment + struct IfcCompositeCurveSegment : IfcGeometricRepresentationItem, ObjectHelper<IfcCompositeCurveSegment,3> { IfcCompositeCurveSegment() : Object("IfcCompositeCurveSegment") {} + IfcTransitionCode::Out Transition; + BOOLEAN::Out SameSense; + Lazy< IfcCurve > ParentCurve; + }; + // C++ wrapper for IfcRectangleProfileDef + struct IfcRectangleProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcRectangleProfileDef,2> { IfcRectangleProfileDef() : Object("IfcRectangleProfileDef") {} + IfcPositiveLengthMeasure::Out XDim; + IfcPositiveLengthMeasure::Out YDim; }; - // C++ wrapper for IfcGridPlacement - struct IfcGridPlacement : IfcObjectPlacement, ObjectHelper<IfcGridPlacement,2> { IfcGridPlacement() : Object("IfcGridPlacement") {} - Lazy< NotImplemented > PlacementLocation; - Maybe< Lazy< NotImplemented > > PlacementRefDirection; + // C++ wrapper for IfcBuildingElementProxy + struct IfcBuildingElementProxy : IfcBuildingElement, ObjectHelper<IfcBuildingElementProxy,1> { IfcBuildingElementProxy() : Object("IfcBuildingElementProxy") {} + Maybe< IfcElementCompositionEnum::Out > CompositionType; }; // C++ wrapper for IfcDistributionControlElementType @@ -1900,54 +1953,83 @@ namespace IFC { }; - // C++ wrapper for IfcRelConnects - struct IfcRelConnects : IfcRelationship, ObjectHelper<IfcRelConnects,0> { IfcRelConnects() : Object("IfcRelConnects") {} + // C++ wrapper for IfcFlowInstrumentType + struct IfcFlowInstrumentType : IfcDistributionControlElementType, ObjectHelper<IfcFlowInstrumentType,1> { IfcFlowInstrumentType() : Object("IfcFlowInstrumentType") {} + IfcFlowInstrumentTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcDraughtingCallout + struct IfcDraughtingCallout : IfcGeometricRepresentationItem, ObjectHelper<IfcDraughtingCallout,1> { IfcDraughtingCallout() : Object("IfcDraughtingCallout") {} + ListOf< IfcDraughtingCalloutElement, 1, 0 >::Out Contents; }; - // C++ wrapper for IfcAnnotation - struct IfcAnnotation : IfcProduct, ObjectHelper<IfcAnnotation,0> { IfcAnnotation() : Object("IfcAnnotation") {} + // C++ wrapper for IfcDimensionCurveDirectedCallout + struct IfcDimensionCurveDirectedCallout : IfcDraughtingCallout, ObjectHelper<IfcDimensionCurveDirectedCallout,0> { IfcDimensionCurveDirectedCallout() : Object("IfcDimensionCurveDirectedCallout") {} }; - // C++ wrapper for IfcPlate - struct IfcPlate : IfcBuildingElement, ObjectHelper<IfcPlate,0> { IfcPlate() : Object("IfcPlate") {} + // C++ wrapper for IfcLinearDimension + struct IfcLinearDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcLinearDimension,0> { IfcLinearDimension() : Object("IfcLinearDimension") {} }; - // C++ wrapper for IfcSolidModel - struct IfcSolidModel : IfcGeometricRepresentationItem, ObjectHelper<IfcSolidModel,0> { IfcSolidModel() : Object("IfcSolidModel") {} + // C++ wrapper for IfcElementAssembly + struct IfcElementAssembly : IfcElement, ObjectHelper<IfcElementAssembly,2> { IfcElementAssembly() : Object("IfcElementAssembly") {} + Maybe< IfcAssemblyPlaceEnum::Out > AssemblyPlace; + IfcElementAssemblyTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcCsgPrimitive3D + struct IfcCsgPrimitive3D : IfcGeometricRepresentationItem, ObjectHelper<IfcCsgPrimitive3D,1> { IfcCsgPrimitive3D() : Object("IfcCsgPrimitive3D") {} + Lazy< IfcAxis2Placement3D > Position; }; - // C++ wrapper for IfcManifoldSolidBrep - struct IfcManifoldSolidBrep : IfcSolidModel, ObjectHelper<IfcManifoldSolidBrep,1> { IfcManifoldSolidBrep() : Object("IfcManifoldSolidBrep") {} - Lazy< IfcClosedShell > Outer; + // C++ wrapper for IfcRightCircularCone + struct IfcRightCircularCone : IfcCsgPrimitive3D, ObjectHelper<IfcRightCircularCone,2> { IfcRightCircularCone() : Object("IfcRightCircularCone") {} + IfcPositiveLengthMeasure::Out Height; + IfcPositiveLengthMeasure::Out BottomRadius; }; - // C++ wrapper for IfcFlowStorageDeviceType - struct IfcFlowStorageDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowStorageDeviceType,0> { IfcFlowStorageDeviceType() : Object("IfcFlowStorageDeviceType") {} + // C++ wrapper for IfcProjectOrder + struct IfcProjectOrder : IfcControl, ObjectHelper<IfcProjectOrder,3> { IfcProjectOrder() : Object("IfcProjectOrder") {} + IfcIdentifier::Out ID; + IfcProjectOrderTypeEnum::Out PredefinedType; + Maybe< IfcLabel::Out > Status; + }; + // C++ wrapper for IfcLShapeProfileDef + struct IfcLShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcLShapeProfileDef,8> { IfcLShapeProfileDef() : Object("IfcLShapeProfileDef") {} + IfcPositiveLengthMeasure::Out Depth; + Maybe< IfcPositiveLengthMeasure::Out > Width; + IfcPositiveLengthMeasure::Out Thickness; + Maybe< IfcPositiveLengthMeasure::Out > FilletRadius; + Maybe< IfcPositiveLengthMeasure::Out > EdgeRadius; + Maybe< IfcPlaneAngleMeasure::Out > LegSlope; + Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX; + Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; }; - // C++ wrapper for IfcStructuralItem - struct IfcStructuralItem : IfcProduct, ObjectHelper<IfcStructuralItem,0> { IfcStructuralItem() : Object("IfcStructuralItem") {} + // C++ wrapper for IfcAngularDimension + struct IfcAngularDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcAngularDimension,0> { IfcAngularDimension() : Object("IfcAngularDimension") {} }; - // C++ wrapper for IfcStructuralMember - struct IfcStructuralMember : IfcStructuralItem, ObjectHelper<IfcStructuralMember,0> { IfcStructuralMember() : Object("IfcStructuralMember") {} - + // C++ wrapper for IfcLocalPlacement + struct IfcLocalPlacement : IfcObjectPlacement, ObjectHelper<IfcLocalPlacement,2> { IfcLocalPlacement() : Object("IfcLocalPlacement") {} + Maybe< Lazy< IfcObjectPlacement > > PlacementRelTo; + IfcAxis2Placement::Out RelativePlacement; }; - // C++ wrapper for IfcStructuralCurveMember - struct IfcStructuralCurveMember : IfcStructuralMember, ObjectHelper<IfcStructuralCurveMember,1> { IfcStructuralCurveMember() : Object("IfcStructuralCurveMember") {} - IfcStructuralCurveTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSweptAreaSolid + struct IfcSweptAreaSolid : IfcSolidModel, ObjectHelper<IfcSweptAreaSolid,2> { IfcSweptAreaSolid() : Object("IfcSweptAreaSolid") {} + Lazy< IfcProfileDef > SweptArea; + Lazy< IfcAxis2Placement3D > Position; }; - // C++ wrapper for IfcStructuralConnection - struct IfcStructuralConnection : IfcStructuralItem, ObjectHelper<IfcStructuralConnection,1> { IfcStructuralConnection() : Object("IfcStructuralConnection") {} - Maybe< Lazy< NotImplemented > > AppliedCondition; + // C++ wrapper for IfcRevolvedAreaSolid + struct IfcRevolvedAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcRevolvedAreaSolid,2> { IfcRevolvedAreaSolid() : Object("IfcRevolvedAreaSolid") {} + Lazy< IfcAxis1Placement > Axis; + IfcPlaneAngleMeasure::Out Angle; }; // C++ wrapper for IfcStructuralSurfaceConnection @@ -1955,403 +2037,477 @@ namespace IFC { }; - // C++ wrapper for IfcCoilType - struct IfcCoilType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCoilType,1> { IfcCoilType() : Object("IfcCoilType") {} - IfcCoilTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcRadiusDimension + struct IfcRadiusDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcRadiusDimension,0> { IfcRadiusDimension() : Object("IfcRadiusDimension") {} - // C++ wrapper for IfcDuctFittingType - struct IfcDuctFittingType : IfcFlowFittingType, ObjectHelper<IfcDuctFittingType,1> { IfcDuctFittingType() : Object("IfcDuctFittingType") {} - IfcDuctFittingTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcStyledItem - struct IfcStyledItem : IfcRepresentationItem, ObjectHelper<IfcStyledItem,3> { IfcStyledItem() : Object("IfcStyledItem") {} - Maybe< Lazy< IfcRepresentationItem > > Item; - ListOf< Lazy< IfcPresentationStyleAssignment >, 1, 0 > Styles; - Maybe< IfcLabel::Out > Name; + // C++ wrapper for IfcSweptDiskSolid + struct IfcSweptDiskSolid : IfcSolidModel, ObjectHelper<IfcSweptDiskSolid,5> { IfcSweptDiskSolid() : Object("IfcSweptDiskSolid") {} + Lazy< IfcCurve > Directrix; + IfcPositiveLengthMeasure::Out Radius; + Maybe< IfcPositiveLengthMeasure::Out > InnerRadius; + IfcParameterValue::Out StartParam; + IfcParameterValue::Out EndParam; }; - // C++ wrapper for IfcAnnotationOccurrence - struct IfcAnnotationOccurrence : IfcStyledItem, ObjectHelper<IfcAnnotationOccurrence,0> { IfcAnnotationOccurrence() : Object("IfcAnnotationOccurrence") {} + // C++ wrapper for IfcHalfSpaceSolid + struct IfcHalfSpaceSolid : IfcGeometricRepresentationItem, ObjectHelper<IfcHalfSpaceSolid,2> { IfcHalfSpaceSolid() : Object("IfcHalfSpaceSolid") {} + Lazy< IfcSurface > BaseSurface; + BOOLEAN::Out AgreementFlag; + }; + // C++ wrapper for IfcPolygonalBoundedHalfSpace + struct IfcPolygonalBoundedHalfSpace : IfcHalfSpaceSolid, ObjectHelper<IfcPolygonalBoundedHalfSpace,2> { IfcPolygonalBoundedHalfSpace() : Object("IfcPolygonalBoundedHalfSpace") {} + Lazy< IfcAxis2Placement3D > Position; + Lazy< IfcBoundedCurve > PolygonalBoundary; }; - // C++ wrapper for IfcAnnotationCurveOccurrence - struct IfcAnnotationCurveOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationCurveOccurrence,0> { IfcAnnotationCurveOccurrence() : Object("IfcAnnotationCurveOccurrence") {} + // C++ wrapper for IfcTimeSeriesSchedule + struct IfcTimeSeriesSchedule : IfcControl, ObjectHelper<IfcTimeSeriesSchedule,3> { IfcTimeSeriesSchedule() : Object("IfcTimeSeriesSchedule") {} + Maybe< ListOf< IfcDateTimeSelect, 1, 0 >::Out > ApplicableDates; + IfcTimeSeriesScheduleTypeEnum::Out TimeSeriesScheduleType; + Lazy< NotImplemented > TimeSeries; + }; + // C++ wrapper for IfcCooledBeamType + struct IfcCooledBeamType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCooledBeamType,1> { IfcCooledBeamType() : Object("IfcCooledBeamType") {} + IfcCooledBeamTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcDimensionCurve - struct IfcDimensionCurve : IfcAnnotationCurveOccurrence, ObjectHelper<IfcDimensionCurve,0> { IfcDimensionCurve() : Object("IfcDimensionCurve") {} + // C++ wrapper for IfcProject + struct IfcProject : IfcObject, ObjectHelper<IfcProject,4> { IfcProject() : Object("IfcProject") {} + Maybe< IfcLabel::Out > LongName; + Maybe< IfcLabel::Out > Phase; + ListOf< Lazy< IfcRepresentationContext >, 1, 0 > RepresentationContexts; + Lazy< IfcUnitAssignment > UnitsInContext; + }; + // C++ wrapper for IfcEvaporatorType + struct IfcEvaporatorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcEvaporatorType,1> { IfcEvaporatorType() : Object("IfcEvaporatorType") {} + IfcEvaporatorTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcBoundedCurve - struct IfcBoundedCurve : IfcCurve, ObjectHelper<IfcBoundedCurve,0> { IfcBoundedCurve() : Object("IfcBoundedCurve") {} + // C++ wrapper for IfcLaborResource + struct IfcLaborResource : IfcConstructionResource, ObjectHelper<IfcLaborResource,1> { IfcLaborResource() : Object("IfcLaborResource") {} + Maybe< IfcText::Out > SkillSet; + }; + // C++ wrapper for IfcPropertyBoundedValue + struct IfcPropertyBoundedValue : IfcSimpleProperty, ObjectHelper<IfcPropertyBoundedValue,3> { IfcPropertyBoundedValue() : Object("IfcPropertyBoundedValue") {} + Maybe< IfcValue::Out > UpperBoundValue; + Maybe< IfcValue::Out > LowerBoundValue; + Maybe< IfcUnit::Out > Unit; }; - // C++ wrapper for IfcAxis1Placement - struct IfcAxis1Placement : IfcPlacement, ObjectHelper<IfcAxis1Placement,1> { IfcAxis1Placement() : Object("IfcAxis1Placement") {} - Maybe< Lazy< IfcDirection > > Axis; + // C++ wrapper for IfcRampFlightType + struct IfcRampFlightType : IfcBuildingElementType, ObjectHelper<IfcRampFlightType,1> { IfcRampFlightType() : Object("IfcRampFlightType") {} + IfcRampFlightTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcStructuralPointAction - struct IfcStructuralPointAction : IfcStructuralAction, ObjectHelper<IfcStructuralPointAction,0> { IfcStructuralPointAction() : Object("IfcStructuralPointAction") {} + // C++ wrapper for IfcMember + struct IfcMember : IfcBuildingElement, ObjectHelper<IfcMember,0> { IfcMember() : Object("IfcMember") {} }; - // C++ wrapper for IfcSpatialStructureElement - struct IfcSpatialStructureElement : IfcProduct, ObjectHelper<IfcSpatialStructureElement,2> { IfcSpatialStructureElement() : Object("IfcSpatialStructureElement") {} - Maybe< IfcLabel::Out > LongName; - IfcElementCompositionEnum::Out CompositionType; + // C++ wrapper for IfcTubeBundleType + struct IfcTubeBundleType : IfcEnergyConversionDeviceType, ObjectHelper<IfcTubeBundleType,1> { IfcTubeBundleType() : Object("IfcTubeBundleType") {} + IfcTubeBundleTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcSpace - struct IfcSpace : IfcSpatialStructureElement, ObjectHelper<IfcSpace,2> { IfcSpace() : Object("IfcSpace") {} - IfcInternalOrExternalEnum::Out InteriorOrExteriorSpace; - Maybe< IfcLengthMeasure::Out > ElevationWithFlooring; + // C++ wrapper for IfcValveType + struct IfcValveType : IfcFlowControllerType, ObjectHelper<IfcValveType,1> { IfcValveType() : Object("IfcValveType") {} + IfcValveTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcContextDependentUnit - struct IfcContextDependentUnit : IfcNamedUnit, ObjectHelper<IfcContextDependentUnit,1> { IfcContextDependentUnit() : Object("IfcContextDependentUnit") {} - IfcLabel::Out Name; + // C++ wrapper for IfcTrimmedCurve + struct IfcTrimmedCurve : IfcBoundedCurve, ObjectHelper<IfcTrimmedCurve,5> { IfcTrimmedCurve() : Object("IfcTrimmedCurve") {} + Lazy< IfcCurve > BasisCurve; + ListOf< IfcTrimmingSelect, 1, 2 >::Out Trim1; + ListOf< IfcTrimmingSelect, 1, 2 >::Out Trim2; + BOOLEAN::Out SenseAgreement; + IfcTrimmingPreference::Out MasterRepresentation; }; - // C++ wrapper for IfcCoolingTowerType - struct IfcCoolingTowerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCoolingTowerType,1> { IfcCoolingTowerType() : Object("IfcCoolingTowerType") {} - IfcCoolingTowerTypeEnum::Out PredefinedType; + // C++ wrapper for IfcRelDefines + struct IfcRelDefines : IfcRelationship, ObjectHelper<IfcRelDefines,1> { IfcRelDefines() : Object("IfcRelDefines") {} + ListOf< Lazy< IfcObject >, 1, 0 > RelatedObjects; }; - // C++ wrapper for IfcFacetedBrepWithVoids - struct IfcFacetedBrepWithVoids : IfcManifoldSolidBrep, ObjectHelper<IfcFacetedBrepWithVoids,1> { IfcFacetedBrepWithVoids() : Object("IfcFacetedBrepWithVoids") {} - ListOf< Lazy< IfcClosedShell >, 1, 0 > Voids; + // C++ wrapper for IfcRelDefinesByProperties + struct IfcRelDefinesByProperties : IfcRelDefines, ObjectHelper<IfcRelDefinesByProperties,1> { IfcRelDefinesByProperties() : Object("IfcRelDefinesByProperties") {} + Lazy< IfcPropertySetDefinition > RelatingPropertyDefinition; }; - // C++ wrapper for IfcValveType - struct IfcValveType : IfcFlowControllerType, ObjectHelper<IfcValveType,1> { IfcValveType() : Object("IfcValveType") {} - IfcValveTypeEnum::Out PredefinedType; + // C++ wrapper for IfcActor + struct IfcActor : IfcObject, ObjectHelper<IfcActor,1> { IfcActor() : Object("IfcActor") {} + IfcActorSelect::Out TheActor; }; - // C++ wrapper for IfcSystemFurnitureElementType - struct IfcSystemFurnitureElementType : IfcFurnishingElementType, ObjectHelper<IfcSystemFurnitureElementType,0> { IfcSystemFurnitureElementType() : Object("IfcSystemFurnitureElementType") {} - + // C++ wrapper for IfcOccupant + struct IfcOccupant : IfcActor, ObjectHelper<IfcOccupant,1> { IfcOccupant() : Object("IfcOccupant") {} + IfcOccupantTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcDiscreteAccessory - struct IfcDiscreteAccessory : IfcElementComponent, ObjectHelper<IfcDiscreteAccessory,0> { IfcDiscreteAccessory() : Object("IfcDiscreteAccessory") {} + // C++ wrapper for IfcHumidifierType + struct IfcHumidifierType : IfcEnergyConversionDeviceType, ObjectHelper<IfcHumidifierType,1> { IfcHumidifierType() : Object("IfcHumidifierType") {} + IfcHumidifierTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcArbitraryOpenProfileDef + struct IfcArbitraryOpenProfileDef : IfcProfileDef, ObjectHelper<IfcArbitraryOpenProfileDef,1> { IfcArbitraryOpenProfileDef() : Object("IfcArbitraryOpenProfileDef") {} + Lazy< IfcBoundedCurve > Curve; }; - // C++ wrapper for IfcBuildingElementType - struct IfcBuildingElementType : IfcElementType, ObjectHelper<IfcBuildingElementType,0> { IfcBuildingElementType() : Object("IfcBuildingElementType") {} + // C++ wrapper for IfcPermit + struct IfcPermit : IfcControl, ObjectHelper<IfcPermit,1> { IfcPermit() : Object("IfcPermit") {} + IfcIdentifier::Out PermitID; + }; + // C++ wrapper for IfcOffsetCurve3D + struct IfcOffsetCurve3D : IfcCurve, ObjectHelper<IfcOffsetCurve3D,4> { IfcOffsetCurve3D() : Object("IfcOffsetCurve3D") {} + Lazy< IfcCurve > BasisCurve; + IfcLengthMeasure::Out Distance; + LOGICAL::Out SelfIntersect; + Lazy< IfcDirection > RefDirection; }; - // C++ wrapper for IfcRailingType - struct IfcRailingType : IfcBuildingElementType, ObjectHelper<IfcRailingType,1> { IfcRailingType() : Object("IfcRailingType") {} - IfcRailingTypeEnum::Out PredefinedType; + // C++ wrapper for IfcLightSource + struct IfcLightSource : IfcGeometricRepresentationItem, ObjectHelper<IfcLightSource,4> { IfcLightSource() : Object("IfcLightSource") {} + Maybe< IfcLabel::Out > Name; + Lazy< IfcColourRgb > LightColour; + Maybe< IfcNormalisedRatioMeasure::Out > AmbientIntensity; + Maybe< IfcNormalisedRatioMeasure::Out > Intensity; }; - // C++ wrapper for IfcGasTerminalType - struct IfcGasTerminalType : IfcFlowTerminalType, ObjectHelper<IfcGasTerminalType,1> { IfcGasTerminalType() : Object("IfcGasTerminalType") {} - IfcGasTerminalTypeEnum::Out PredefinedType; + // C++ wrapper for IfcLightSourcePositional + struct IfcLightSourcePositional : IfcLightSource, ObjectHelper<IfcLightSourcePositional,5> { IfcLightSourcePositional() : Object("IfcLightSourcePositional") {} + Lazy< IfcCartesianPoint > Position; + IfcPositiveLengthMeasure::Out Radius; + IfcReal::Out ConstantAttenuation; + IfcReal::Out DistanceAttenuation; + IfcReal::Out QuadricAttenuation; }; - // C++ wrapper for IfcSpaceProgram - struct IfcSpaceProgram : IfcControl, ObjectHelper<IfcSpaceProgram,5> { IfcSpaceProgram() : Object("IfcSpaceProgram") {} - IfcIdentifier::Out SpaceProgramIdentifier; - Maybe< IfcAreaMeasure::Out > MaxRequiredArea; - Maybe< IfcAreaMeasure::Out > MinRequiredArea; - Maybe< Lazy< IfcSpatialStructureElement > > RequestedLocation; - IfcAreaMeasure::Out StandardRequiredArea; + // C++ wrapper for IfcCompositeProfileDef + struct IfcCompositeProfileDef : IfcProfileDef, ObjectHelper<IfcCompositeProfileDef,2> { IfcCompositeProfileDef() : Object("IfcCompositeProfileDef") {} + ListOf< Lazy< IfcProfileDef >, 2, 0 > Profiles; + Maybe< IfcLabel::Out > Label; }; - // C++ wrapper for IfcCovering - struct IfcCovering : IfcBuildingElement, ObjectHelper<IfcCovering,1> { IfcCovering() : Object("IfcCovering") {} - Maybe< IfcCoveringTypeEnum::Out > PredefinedType; + // C++ wrapper for IfcRamp + struct IfcRamp : IfcBuildingElement, ObjectHelper<IfcRamp,1> { IfcRamp() : Object("IfcRamp") {} + IfcRampTypeEnum::Out ShapeType; }; - // C++ wrapper for IfcPresentationStyle - struct IfcPresentationStyle : ObjectHelper<IfcPresentationStyle,1> { IfcPresentationStyle() : Object("IfcPresentationStyle") {} - Maybe< IfcLabel::Out > Name; + // C++ wrapper for IfcFlowMovingDevice + struct IfcFlowMovingDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowMovingDevice,0> { IfcFlowMovingDevice() : Object("IfcFlowMovingDevice") {} + }; - // C++ wrapper for IfcElectricHeaterType - struct IfcElectricHeaterType : IfcFlowTerminalType, ObjectHelper<IfcElectricHeaterType,1> { IfcElectricHeaterType() : Object("IfcElectricHeaterType") {} - IfcElectricHeaterTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSpaceHeaterType + struct IfcSpaceHeaterType : IfcEnergyConversionDeviceType, ObjectHelper<IfcSpaceHeaterType,1> { IfcSpaceHeaterType() : Object("IfcSpaceHeaterType") {} + IfcSpaceHeaterTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcBuildingStorey - struct IfcBuildingStorey : IfcSpatialStructureElement, ObjectHelper<IfcBuildingStorey,1> { IfcBuildingStorey() : Object("IfcBuildingStorey") {} - Maybe< IfcLengthMeasure::Out > Elevation; + // C++ wrapper for IfcLampType + struct IfcLampType : IfcFlowTerminalType, ObjectHelper<IfcLampType,1> { IfcLampType() : Object("IfcLampType") {} + IfcLampTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcVertex - struct IfcVertex : IfcTopologicalRepresentationItem, ObjectHelper<IfcVertex,0> { IfcVertex() : Object("IfcVertex") {} + // C++ wrapper for IfcBuildingElementComponent + struct IfcBuildingElementComponent : IfcBuildingElement, ObjectHelper<IfcBuildingElementComponent,0> { IfcBuildingElementComponent() : Object("IfcBuildingElementComponent") {} }; - // C++ wrapper for IfcVertexPoint - struct IfcVertexPoint : IfcVertex, ObjectHelper<IfcVertexPoint,1> { IfcVertexPoint() : Object("IfcVertexPoint") {} - Lazy< IfcPoint > VertexGeometry; + // C++ wrapper for IfcReinforcingElement + struct IfcReinforcingElement : IfcBuildingElementComponent, ObjectHelper<IfcReinforcingElement,1> { IfcReinforcingElement() : Object("IfcReinforcingElement") {} + Maybe< IfcLabel::Out > SteelGrade; }; - // C++ wrapper for IfcFlowInstrumentType - struct IfcFlowInstrumentType : IfcDistributionControlElementType, ObjectHelper<IfcFlowInstrumentType,1> { IfcFlowInstrumentType() : Object("IfcFlowInstrumentType") {} - IfcFlowInstrumentTypeEnum::Out PredefinedType; + // C++ wrapper for IfcReinforcingBar + struct IfcReinforcingBar : IfcReinforcingElement, ObjectHelper<IfcReinforcingBar,5> { IfcReinforcingBar() : Object("IfcReinforcingBar") {} + IfcPositiveLengthMeasure::Out NominalDiameter; + IfcAreaMeasure::Out CrossSectionArea; + Maybe< IfcPositiveLengthMeasure::Out > BarLength; + IfcReinforcingBarRoleEnum::Out BarRole; + Maybe< IfcReinforcingBarSurfaceEnum::Out > BarSurface; }; - // C++ wrapper for IfcParameterizedProfileDef - struct IfcParameterizedProfileDef : IfcProfileDef, ObjectHelper<IfcParameterizedProfileDef,1> { IfcParameterizedProfileDef() : Object("IfcParameterizedProfileDef") {} - Lazy< IfcAxis2Placement2D > Position; + // C++ wrapper for IfcElectricHeaterType + struct IfcElectricHeaterType : IfcFlowTerminalType, ObjectHelper<IfcElectricHeaterType,1> { IfcElectricHeaterType() : Object("IfcElectricHeaterType") {} + IfcElectricHeaterTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcUShapeProfileDef - struct IfcUShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcUShapeProfileDef,8> { IfcUShapeProfileDef() : Object("IfcUShapeProfileDef") {} + // C++ wrapper for IfcTShapeProfileDef + struct IfcTShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcTShapeProfileDef,10> { IfcTShapeProfileDef() : Object("IfcTShapeProfileDef") {} IfcPositiveLengthMeasure::Out Depth; IfcPositiveLengthMeasure::Out FlangeWidth; IfcPositiveLengthMeasure::Out WebThickness; IfcPositiveLengthMeasure::Out FlangeThickness; Maybe< IfcPositiveLengthMeasure::Out > FilletRadius; - Maybe< IfcPositiveLengthMeasure::Out > EdgeRadius; + Maybe< IfcPositiveLengthMeasure::Out > FlangeEdgeRadius; + Maybe< IfcPositiveLengthMeasure::Out > WebEdgeRadius; + Maybe< IfcPlaneAngleMeasure::Out > WebSlope; Maybe< IfcPlaneAngleMeasure::Out > FlangeSlope; - Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX; + Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; }; - // C++ wrapper for IfcRamp - struct IfcRamp : IfcBuildingElement, ObjectHelper<IfcRamp,1> { IfcRamp() : Object("IfcRamp") {} - IfcRampTypeEnum::Out ShapeType; + // C++ wrapper for IfcStructuralActivity + struct IfcStructuralActivity : IfcProduct, ObjectHelper<IfcStructuralActivity,2> { IfcStructuralActivity() : Object("IfcStructuralActivity") {} + Lazy< NotImplemented > AppliedLoad; + IfcGlobalOrLocalEnum::Out GlobalOrLocal; }; - // C++ wrapper for IfcCompositeCurve - struct IfcCompositeCurve : IfcBoundedCurve, ObjectHelper<IfcCompositeCurve,2> { IfcCompositeCurve() : Object("IfcCompositeCurve") {} - ListOf< Lazy< IfcCompositeCurveSegment >, 1, 0 > Segments; - LOGICAL::Out SelfIntersect; + // C++ wrapper for IfcStructuralAction + struct IfcStructuralAction : IfcStructuralActivity, ObjectHelper<IfcStructuralAction,2> { IfcStructuralAction() : Object("IfcStructuralAction") {} + BOOLEAN::Out DestabilizingLoad; + Maybe< Lazy< IfcStructuralReaction > > CausedBy; }; - // C++ wrapper for IfcStructuralCurveMemberVarying - struct IfcStructuralCurveMemberVarying : IfcStructuralCurveMember, ObjectHelper<IfcStructuralCurveMemberVarying,0> { IfcStructuralCurveMemberVarying() : Object("IfcStructuralCurveMemberVarying") {} + // C++ wrapper for IfcDuctFittingType + struct IfcDuctFittingType : IfcFlowFittingType, ObjectHelper<IfcDuctFittingType,1> { IfcDuctFittingType() : Object("IfcDuctFittingType") {} + IfcDuctFittingTypeEnum::Out PredefinedType; + }; + + // C++ wrapper for IfcCartesianTransformationOperator2D + struct IfcCartesianTransformationOperator2D : IfcCartesianTransformationOperator, ObjectHelper<IfcCartesianTransformationOperator2D,0> { IfcCartesianTransformationOperator2D() : Object("IfcCartesianTransformationOperator2D") {} }; - // C++ wrapper for IfcRampFlightType - struct IfcRampFlightType : IfcBuildingElementType, ObjectHelper<IfcRampFlightType,1> { IfcRampFlightType() : Object("IfcRampFlightType") {} - IfcRampFlightTypeEnum::Out PredefinedType; + // C++ wrapper for IfcCartesianTransformationOperator2DnonUniform + struct IfcCartesianTransformationOperator2DnonUniform : IfcCartesianTransformationOperator2D, ObjectHelper<IfcCartesianTransformationOperator2DnonUniform,1> { IfcCartesianTransformationOperator2DnonUniform() : Object("IfcCartesianTransformationOperator2DnonUniform") {} + Maybe< REAL::Out > Scale2; }; - // C++ wrapper for IfcDraughtingCallout - struct IfcDraughtingCallout : IfcGeometricRepresentationItem, ObjectHelper<IfcDraughtingCallout,1> { IfcDraughtingCallout() : Object("IfcDraughtingCallout") {} - ListOf< IfcDraughtingCalloutElement, 1, 0 >::Out Contents; + // C++ wrapper for IfcVirtualElement + struct IfcVirtualElement : IfcElement, ObjectHelper<IfcVirtualElement,0> { IfcVirtualElement() : Object("IfcVirtualElement") {} + }; - // C++ wrapper for IfcDimensionCurveDirectedCallout - struct IfcDimensionCurveDirectedCallout : IfcDraughtingCallout, ObjectHelper<IfcDimensionCurveDirectedCallout,0> { IfcDimensionCurveDirectedCallout() : Object("IfcDimensionCurveDirectedCallout") {} + // C++ wrapper for IfcRightCircularCylinder + struct IfcRightCircularCylinder : IfcCsgPrimitive3D, ObjectHelper<IfcRightCircularCylinder,2> { IfcRightCircularCylinder() : Object("IfcRightCircularCylinder") {} + IfcPositiveLengthMeasure::Out Height; + IfcPositiveLengthMeasure::Out Radius; + }; + // C++ wrapper for IfcOutletType + struct IfcOutletType : IfcFlowTerminalType, ObjectHelper<IfcOutletType,1> { IfcOutletType() : Object("IfcOutletType") {} + IfcOutletTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcRadiusDimension - struct IfcRadiusDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcRadiusDimension,0> { IfcRadiusDimension() : Object("IfcRadiusDimension") {} + // C++ wrapper for IfcRelDecomposes + struct IfcRelDecomposes : IfcRelationship, ObjectHelper<IfcRelDecomposes,2> { IfcRelDecomposes() : Object("IfcRelDecomposes") {} + Lazy< IfcObjectDefinition > RelatingObject; + ListOf< Lazy< IfcObjectDefinition >, 1, 0 > RelatedObjects; + }; + // C++ wrapper for IfcCovering + struct IfcCovering : IfcBuildingElement, ObjectHelper<IfcCovering,1> { IfcCovering() : Object("IfcCovering") {} + Maybe< IfcCoveringTypeEnum::Out > PredefinedType; }; - // C++ wrapper for IfcEdgeFeature - struct IfcEdgeFeature : IfcFeatureElementSubtraction, ObjectHelper<IfcEdgeFeature,1> { IfcEdgeFeature() : Object("IfcEdgeFeature") {} - Maybe< IfcPositiveLengthMeasure::Out > FeatureLength; + // C++ wrapper for IfcPolyline + struct IfcPolyline : IfcBoundedCurve, ObjectHelper<IfcPolyline,1> { IfcPolyline() : Object("IfcPolyline") {} + ListOf< Lazy< IfcCartesianPoint >, 2, 0 > Points; }; - // C++ wrapper for IfcSweptAreaSolid - struct IfcSweptAreaSolid : IfcSolidModel, ObjectHelper<IfcSweptAreaSolid,2> { IfcSweptAreaSolid() : Object("IfcSweptAreaSolid") {} - Lazy< IfcProfileDef > SweptArea; - Lazy< IfcAxis2Placement3D > Position; + // C++ wrapper for IfcPath + struct IfcPath : IfcTopologicalRepresentationItem, ObjectHelper<IfcPath,1> { IfcPath() : Object("IfcPath") {} + ListOf< Lazy< IfcOrientedEdge >, 1, 0 > EdgeList; }; - // C++ wrapper for IfcExtrudedAreaSolid - struct IfcExtrudedAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcExtrudedAreaSolid,2> { IfcExtrudedAreaSolid() : Object("IfcExtrudedAreaSolid") {} - Lazy< IfcDirection > ExtrudedDirection; - IfcPositiveLengthMeasure::Out Depth; + // C++ wrapper for IfcElementComponent + struct IfcElementComponent : IfcElement, ObjectHelper<IfcElementComponent,0> { IfcElementComponent() : Object("IfcElementComponent") {} + }; - // C++ wrapper for IfcAnnotationTextOccurrence - struct IfcAnnotationTextOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationTextOccurrence,0> { IfcAnnotationTextOccurrence() : Object("IfcAnnotationTextOccurrence") {} + // C++ wrapper for IfcFastener + struct IfcFastener : IfcElementComponent, ObjectHelper<IfcFastener,0> { IfcFastener() : Object("IfcFastener") {} }; - // C++ wrapper for IfcStair - struct IfcStair : IfcBuildingElement, ObjectHelper<IfcStair,1> { IfcStair() : Object("IfcStair") {} - IfcStairTypeEnum::Out ShapeType; + // C++ wrapper for IfcMappedItem + struct IfcMappedItem : IfcRepresentationItem, ObjectHelper<IfcMappedItem,2> { IfcMappedItem() : Object("IfcMappedItem") {} + Lazy< IfcRepresentationMap > MappingSource; + Lazy< IfcCartesianTransformationOperator > MappingTarget; }; - // C++ wrapper for IfcFillAreaStyleTileSymbolWithStyle - struct IfcFillAreaStyleTileSymbolWithStyle : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleTileSymbolWithStyle,1> { IfcFillAreaStyleTileSymbolWithStyle() : Object("IfcFillAreaStyleTileSymbolWithStyle") {} - Lazy< IfcAnnotationSymbolOccurrence > Symbol; + // C++ wrapper for IfcRectangularPyramid + struct IfcRectangularPyramid : IfcCsgPrimitive3D, ObjectHelper<IfcRectangularPyramid,3> { IfcRectangularPyramid() : Object("IfcRectangularPyramid") {} + IfcPositiveLengthMeasure::Out XLength; + IfcPositiveLengthMeasure::Out YLength; + IfcPositiveLengthMeasure::Out Height; }; - // C++ wrapper for IfcAnnotationSymbolOccurrence - struct IfcAnnotationSymbolOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationSymbolOccurrence,0> { IfcAnnotationSymbolOccurrence() : Object("IfcAnnotationSymbolOccurrence") {} + // C++ wrapper for IfcCrewResource + struct IfcCrewResource : IfcConstructionResource, ObjectHelper<IfcCrewResource,0> { IfcCrewResource() : Object("IfcCrewResource") {} }; - // C++ wrapper for IfcTerminatorSymbol - struct IfcTerminatorSymbol : IfcAnnotationSymbolOccurrence, ObjectHelper<IfcTerminatorSymbol,1> { IfcTerminatorSymbol() : Object("IfcTerminatorSymbol") {} - Lazy< IfcAnnotationCurveOccurrence > AnnotatedCurve; + // C++ wrapper for IfcNamedUnit + struct IfcNamedUnit : ObjectHelper<IfcNamedUnit,2> { IfcNamedUnit() : Object("IfcNamedUnit") {} + Lazy< NotImplemented > Dimensions; + IfcUnitEnum::Out UnitType; }; - // C++ wrapper for IfcDimensionCurveTerminator - struct IfcDimensionCurveTerminator : IfcTerminatorSymbol, ObjectHelper<IfcDimensionCurveTerminator,1> { IfcDimensionCurveTerminator() : Object("IfcDimensionCurveTerminator") {} - IfcDimensionExtentUsage::Out Role; + // C++ wrapper for IfcContextDependentUnit + struct IfcContextDependentUnit : IfcNamedUnit, ObjectHelper<IfcContextDependentUnit,1> { IfcContextDependentUnit() : Object("IfcContextDependentUnit") {} + IfcLabel::Out Name; }; - // C++ wrapper for IfcRectangleProfileDef - struct IfcRectangleProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcRectangleProfileDef,2> { IfcRectangleProfileDef() : Object("IfcRectangleProfileDef") {} - IfcPositiveLengthMeasure::Out XDim; - IfcPositiveLengthMeasure::Out YDim; + // C++ wrapper for IfcUnitaryEquipmentType + struct IfcUnitaryEquipmentType : IfcEnergyConversionDeviceType, ObjectHelper<IfcUnitaryEquipmentType,1> { IfcUnitaryEquipmentType() : Object("IfcUnitaryEquipmentType") {} + IfcUnitaryEquipmentTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcRectangleHollowProfileDef - struct IfcRectangleHollowProfileDef : IfcRectangleProfileDef, ObjectHelper<IfcRectangleHollowProfileDef,3> { IfcRectangleHollowProfileDef() : Object("IfcRectangleHollowProfileDef") {} - IfcPositiveLengthMeasure::Out WallThickness; - Maybe< IfcPositiveLengthMeasure::Out > InnerFilletRadius; - Maybe< IfcPositiveLengthMeasure::Out > OuterFilletRadius; + // C++ wrapper for IfcRoof + struct IfcRoof : IfcBuildingElement, ObjectHelper<IfcRoof,1> { IfcRoof() : Object("IfcRoof") {} + IfcRoofTypeEnum::Out ShapeType; }; - // C++ wrapper for IfcLocalPlacement - struct IfcLocalPlacement : IfcObjectPlacement, ObjectHelper<IfcLocalPlacement,2> { IfcLocalPlacement() : Object("IfcLocalPlacement") {} - Maybe< Lazy< IfcObjectPlacement > > PlacementRelTo; - IfcAxis2Placement::Out RelativePlacement; - }; + // C++ wrapper for IfcStructuralMember + struct IfcStructuralMember : IfcStructuralItem, ObjectHelper<IfcStructuralMember,0> { IfcStructuralMember() : Object("IfcStructuralMember") {} - // C++ wrapper for IfcTask - struct IfcTask : IfcProcess, ObjectHelper<IfcTask,5> { IfcTask() : Object("IfcTask") {} - IfcIdentifier::Out TaskId; - Maybe< IfcLabel::Out > Status; - Maybe< IfcLabel::Out > WorkMethod; - BOOLEAN::Out IsMilestone; - Maybe< INTEGER::Out > Priority; }; - // C++ wrapper for IfcAnnotationFillAreaOccurrence - struct IfcAnnotationFillAreaOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationFillAreaOccurrence,2> { IfcAnnotationFillAreaOccurrence() : Object("IfcAnnotationFillAreaOccurrence") {} - Maybe< Lazy< IfcPoint > > FillStyleTarget; - Maybe< IfcGlobalOrLocalEnum::Out > GlobalOrLocal; + // C++ wrapper for IfcStyleModel + struct IfcStyleModel : IfcRepresentation, ObjectHelper<IfcStyleModel,0> { IfcStyleModel() : Object("IfcStyleModel") {} + }; - // C++ wrapper for IfcFace - struct IfcFace : IfcTopologicalRepresentationItem, ObjectHelper<IfcFace,1> { IfcFace() : Object("IfcFace") {} - ListOf< Lazy< IfcFaceBound >, 1, 0 > Bounds; + // C++ wrapper for IfcStyledRepresentation + struct IfcStyledRepresentation : IfcStyleModel, ObjectHelper<IfcStyledRepresentation,0> { IfcStyledRepresentation() : Object("IfcStyledRepresentation") {} + }; - // C++ wrapper for IfcFlowSegmentType - struct IfcFlowSegmentType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowSegmentType,0> { IfcFlowSegmentType() : Object("IfcFlowSegmentType") {} + // C++ wrapper for IfcSpatialStructureElement + struct IfcSpatialStructureElement : IfcProduct, ObjectHelper<IfcSpatialStructureElement,2> { IfcSpatialStructureElement() : Object("IfcSpatialStructureElement") {} + Maybe< IfcLabel::Out > LongName; + IfcElementCompositionEnum::Out CompositionType; + }; + // C++ wrapper for IfcBuilding + struct IfcBuilding : IfcSpatialStructureElement, ObjectHelper<IfcBuilding,3> { IfcBuilding() : Object("IfcBuilding") {} + Maybe< IfcLengthMeasure::Out > ElevationOfRefHeight; + Maybe< IfcLengthMeasure::Out > ElevationOfTerrain; + Maybe< Lazy< NotImplemented > > BuildingAddress; }; - // C++ wrapper for IfcDuctSegmentType - struct IfcDuctSegmentType : IfcFlowSegmentType, ObjectHelper<IfcDuctSegmentType,1> { IfcDuctSegmentType() : Object("IfcDuctSegmentType") {} - IfcDuctSegmentTypeEnum::Out PredefinedType; + // C++ wrapper for IfcConnectedFaceSet + struct IfcConnectedFaceSet : IfcTopologicalRepresentationItem, ObjectHelper<IfcConnectedFaceSet,1> { IfcConnectedFaceSet() : Object("IfcConnectedFaceSet") {} + ListOf< Lazy< IfcFace >, 1, 0 > CfsFaces; }; - // C++ wrapper for IfcConstructionResource - struct IfcConstructionResource : IfcResource, ObjectHelper<IfcConstructionResource,4> { IfcConstructionResource() : Object("IfcConstructionResource") {} - Maybe< IfcIdentifier::Out > ResourceIdentifier; - Maybe< IfcLabel::Out > ResourceGroup; - Maybe< IfcResourceConsumptionEnum::Out > ResourceConsumption; - Maybe< Lazy< IfcMeasureWithUnit > > BaseQuantity; + // C++ wrapper for IfcOpenShell + struct IfcOpenShell : IfcConnectedFaceSet, ObjectHelper<IfcOpenShell,0> { IfcOpenShell() : Object("IfcOpenShell") {} + }; - // C++ wrapper for IfcConstructionEquipmentResource - struct IfcConstructionEquipmentResource : IfcConstructionResource, ObjectHelper<IfcConstructionEquipmentResource,0> { IfcConstructionEquipmentResource() : Object("IfcConstructionEquipmentResource") {} + // C++ wrapper for IfcFacetedBrep + struct IfcFacetedBrep : IfcManifoldSolidBrep, ObjectHelper<IfcFacetedBrep,0> { IfcFacetedBrep() : Object("IfcFacetedBrep") {} }; - // C++ wrapper for IfcSanitaryTerminalType - struct IfcSanitaryTerminalType : IfcFlowTerminalType, ObjectHelper<IfcSanitaryTerminalType,1> { IfcSanitaryTerminalType() : Object("IfcSanitaryTerminalType") {} - IfcSanitaryTerminalTypeEnum::Out PredefinedType; + // C++ wrapper for IfcConic + struct IfcConic : IfcCurve, ObjectHelper<IfcConic,1> { IfcConic() : Object("IfcConic") {} + IfcAxis2Placement::Out Position; }; - // C++ wrapper for IfcCircleProfileDef - struct IfcCircleProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCircleProfileDef,1> { IfcCircleProfileDef() : Object("IfcCircleProfileDef") {} - IfcPositiveLengthMeasure::Out Radius; + // C++ wrapper for IfcCoveringType + struct IfcCoveringType : IfcBuildingElementType, ObjectHelper<IfcCoveringType,1> { IfcCoveringType() : Object("IfcCoveringType") {} + IfcCoveringTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcStructuralReaction - struct IfcStructuralReaction : IfcStructuralActivity, ObjectHelper<IfcStructuralReaction,0> { IfcStructuralReaction() : Object("IfcStructuralReaction") {} + // C++ wrapper for IfcRoundedRectangleProfileDef + struct IfcRoundedRectangleProfileDef : IfcRectangleProfileDef, ObjectHelper<IfcRoundedRectangleProfileDef,1> { IfcRoundedRectangleProfileDef() : Object("IfcRoundedRectangleProfileDef") {} + IfcPositiveLengthMeasure::Out RoundingRadius; + }; + // C++ wrapper for IfcAirTerminalType + struct IfcAirTerminalType : IfcFlowTerminalType, ObjectHelper<IfcAirTerminalType,1> { IfcAirTerminalType() : Object("IfcAirTerminalType") {} + IfcAirTerminalTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcStructuralPointReaction - struct IfcStructuralPointReaction : IfcStructuralReaction, ObjectHelper<IfcStructuralPointReaction,0> { IfcStructuralPointReaction() : Object("IfcStructuralPointReaction") {} + // C++ wrapper for IfcFlowMovingDeviceType + struct IfcFlowMovingDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowMovingDeviceType,0> { IfcFlowMovingDeviceType() : Object("IfcFlowMovingDeviceType") {} }; - // C++ wrapper for IfcRailing - struct IfcRailing : IfcBuildingElement, ObjectHelper<IfcRailing,1> { IfcRailing() : Object("IfcRailing") {} - Maybe< IfcRailingTypeEnum::Out > PredefinedType; + // C++ wrapper for IfcCompressorType + struct IfcCompressorType : IfcFlowMovingDeviceType, ObjectHelper<IfcCompressorType,1> { IfcCompressorType() : Object("IfcCompressorType") {} + IfcCompressorTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcTextLiteral - struct IfcTextLiteral : IfcGeometricRepresentationItem, ObjectHelper<IfcTextLiteral,3> { IfcTextLiteral() : Object("IfcTextLiteral") {} - IfcPresentableText::Out Literal; - IfcAxis2Placement::Out Placement; - IfcTextPath::Out Path; + // C++ wrapper for IfcIShapeProfileDef + struct IfcIShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcIShapeProfileDef,5> { IfcIShapeProfileDef() : Object("IfcIShapeProfileDef") {} + IfcPositiveLengthMeasure::Out OverallWidth; + IfcPositiveLengthMeasure::Out OverallDepth; + IfcPositiveLengthMeasure::Out WebThickness; + IfcPositiveLengthMeasure::Out FlangeThickness; + Maybe< IfcPositiveLengthMeasure::Out > FilletRadius; }; - // C++ wrapper for IfcCartesianTransformationOperator - struct IfcCartesianTransformationOperator : IfcGeometricRepresentationItem, ObjectHelper<IfcCartesianTransformationOperator,4> { IfcCartesianTransformationOperator() : Object("IfcCartesianTransformationOperator") {} - Maybe< Lazy< IfcDirection > > Axis1; - Maybe< Lazy< IfcDirection > > Axis2; - Lazy< IfcCartesianPoint > LocalOrigin; - Maybe< REAL::Out > Scale; + // C++ wrapper for IfcAsymmetricIShapeProfileDef + struct IfcAsymmetricIShapeProfileDef : IfcIShapeProfileDef, ObjectHelper<IfcAsymmetricIShapeProfileDef,4> { IfcAsymmetricIShapeProfileDef() : Object("IfcAsymmetricIShapeProfileDef") {} + IfcPositiveLengthMeasure::Out TopFlangeWidth; + Maybe< IfcPositiveLengthMeasure::Out > TopFlangeThickness; + Maybe< IfcPositiveLengthMeasure::Out > TopFlangeFilletRadius; + Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; }; - // C++ wrapper for IfcLinearDimension - struct IfcLinearDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcLinearDimension,0> { IfcLinearDimension() : Object("IfcLinearDimension") {} - + // C++ wrapper for IfcControllerType + struct IfcControllerType : IfcDistributionControlElementType, ObjectHelper<IfcControllerType,1> { IfcControllerType() : Object("IfcControllerType") {} + IfcControllerTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcDamperType - struct IfcDamperType : IfcFlowControllerType, ObjectHelper<IfcDamperType,1> { IfcDamperType() : Object("IfcDamperType") {} - IfcDamperTypeEnum::Out PredefinedType; + // C++ wrapper for IfcRailing + struct IfcRailing : IfcBuildingElement, ObjectHelper<IfcRailing,1> { IfcRailing() : Object("IfcRailing") {} + Maybe< IfcRailingTypeEnum::Out > PredefinedType; }; - // C++ wrapper for IfcSIUnit - struct IfcSIUnit : IfcNamedUnit, ObjectHelper<IfcSIUnit,2> { IfcSIUnit() : Object("IfcSIUnit") {} - Maybe< IfcSIPrefix::Out > Prefix; - IfcSIUnitName::Out Name; - }; + // C++ wrapper for IfcGroup + struct IfcGroup : IfcObject, ObjectHelper<IfcGroup,0> { IfcGroup() : Object("IfcGroup") {} - // C++ wrapper for IfcMeasureWithUnit - struct IfcMeasureWithUnit : ObjectHelper<IfcMeasureWithUnit,2> { IfcMeasureWithUnit() : Object("IfcMeasureWithUnit") {} - IfcValue::Out ValueComponent; - IfcUnit::Out UnitComponent; }; - // C++ wrapper for IfcDistributionElement - struct IfcDistributionElement : IfcElement, ObjectHelper<IfcDistributionElement,0> { IfcDistributionElement() : Object("IfcDistributionElement") {} + // C++ wrapper for IfcAsset + struct IfcAsset : IfcGroup, ObjectHelper<IfcAsset,9> { IfcAsset() : Object("IfcAsset") {} + IfcIdentifier::Out AssetID; + Lazy< NotImplemented > OriginalValue; + Lazy< NotImplemented > CurrentValue; + Lazy< NotImplemented > TotalReplacementCost; + IfcActorSelect::Out Owner; + IfcActorSelect::Out User; + Lazy< NotImplemented > ResponsiblePerson; + Lazy< NotImplemented > IncorporationDate; + Lazy< NotImplemented > DepreciatedValue; + }; + // C++ wrapper for IfcMaterialDefinitionRepresentation + struct IfcMaterialDefinitionRepresentation : IfcProductRepresentation, ObjectHelper<IfcMaterialDefinitionRepresentation,1> { IfcMaterialDefinitionRepresentation() : Object("IfcMaterialDefinitionRepresentation") {} + Lazy< NotImplemented > RepresentedMaterial; }; - // C++ wrapper for IfcDistributionControlElement - struct IfcDistributionControlElement : IfcDistributionElement, ObjectHelper<IfcDistributionControlElement,1> { IfcDistributionControlElement() : Object("IfcDistributionControlElement") {} - Maybe< IfcIdentifier::Out > ControlElementId; + // C++ wrapper for IfcRailingType + struct IfcRailingType : IfcBuildingElementType, ObjectHelper<IfcRailingType,1> { IfcRailingType() : Object("IfcRailingType") {} + IfcRailingTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcTransformerType - struct IfcTransformerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcTransformerType,1> { IfcTransformerType() : Object("IfcTransformerType") {} - IfcTransformerTypeEnum::Out PredefinedType; + // C++ wrapper for IfcWall + struct IfcWall : IfcBuildingElement, ObjectHelper<IfcWall,0> { IfcWall() : Object("IfcWall") {} + }; - // C++ wrapper for IfcLaborResource - struct IfcLaborResource : IfcConstructionResource, ObjectHelper<IfcLaborResource,1> { IfcLaborResource() : Object("IfcLaborResource") {} - Maybe< IfcText::Out > SkillSet; + // C++ wrapper for IfcStructuralPointConnection + struct IfcStructuralPointConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralPointConnection,0> { IfcStructuralPointConnection() : Object("IfcStructuralPointConnection") {} + }; - // C++ wrapper for IfcDerivedProfileDef - struct IfcDerivedProfileDef : IfcProfileDef, ObjectHelper<IfcDerivedProfileDef,3> { IfcDerivedProfileDef() : Object("IfcDerivedProfileDef") {} - Lazy< IfcProfileDef > ParentProfile; - Lazy< IfcCartesianTransformationOperator2D > Operator; - Maybe< IfcLabel::Out > Label; + // C++ wrapper for IfcPropertyListValue + struct IfcPropertyListValue : IfcSimpleProperty, ObjectHelper<IfcPropertyListValue,2> { IfcPropertyListValue() : Object("IfcPropertyListValue") {} + ListOf< IfcValue, 1, 0 >::Out ListValues; + Maybe< IfcUnit::Out > Unit; }; // C++ wrapper for IfcFurnitureStandard @@ -2359,73 +2515,69 @@ namespace IFC { }; - // C++ wrapper for IfcStairFlightType - struct IfcStairFlightType : IfcBuildingElementType, ObjectHelper<IfcStairFlightType,1> { IfcStairFlightType() : Object("IfcStairFlightType") {} - IfcStairFlightTypeEnum::Out PredefinedType; + // C++ wrapper for IfcElectricGeneratorType + struct IfcElectricGeneratorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcElectricGeneratorType,1> { IfcElectricGeneratorType() : Object("IfcElectricGeneratorType") {} + IfcElectricGeneratorTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcWorkControl - struct IfcWorkControl : IfcControl, ObjectHelper<IfcWorkControl,10> { IfcWorkControl() : Object("IfcWorkControl") {} - IfcIdentifier::Out Identifier; - IfcDateTimeSelect::Out CreationDate; - Maybe< ListOf< Lazy< NotImplemented >, 1, 0 > > Creators; - Maybe< IfcLabel::Out > Purpose; - Maybe< IfcTimeMeasure::Out > Duration; - Maybe< IfcTimeMeasure::Out > TotalFloat; - IfcDateTimeSelect::Out StartTime; - Maybe< IfcDateTimeSelect::Out > FinishTime; - Maybe< IfcWorkControlTypeEnum::Out > WorkControlType; - Maybe< IfcLabel::Out > UserDefinedControlType; + // C++ wrapper for IfcDoor + struct IfcDoor : IfcBuildingElement, ObjectHelper<IfcDoor,2> { IfcDoor() : Object("IfcDoor") {} + Maybe< IfcPositiveLengthMeasure::Out > OverallHeight; + Maybe< IfcPositiveLengthMeasure::Out > OverallWidth; }; - // C++ wrapper for IfcWorkPlan - struct IfcWorkPlan : IfcWorkControl, ObjectHelper<IfcWorkPlan,0> { IfcWorkPlan() : Object("IfcWorkPlan") {} + // C++ wrapper for IfcStyledItem + struct IfcStyledItem : IfcRepresentationItem, ObjectHelper<IfcStyledItem,3> { IfcStyledItem() : Object("IfcStyledItem") {} + Maybe< Lazy< IfcRepresentationItem > > Item; + ListOf< Lazy< IfcPresentationStyleAssignment >, 1, 0 > Styles; + Maybe< IfcLabel::Out > Name; + }; + + // C++ wrapper for IfcAnnotationOccurrence + struct IfcAnnotationOccurrence : IfcStyledItem, ObjectHelper<IfcAnnotationOccurrence,0> { IfcAnnotationOccurrence() : Object("IfcAnnotationOccurrence") {} }; - // C++ wrapper for IfcCondition - struct IfcCondition : IfcGroup, ObjectHelper<IfcCondition,0> { IfcCondition() : Object("IfcCondition") {} + // C++ wrapper for IfcAnnotationSymbolOccurrence + struct IfcAnnotationSymbolOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationSymbolOccurrence,0> { IfcAnnotationSymbolOccurrence() : Object("IfcAnnotationSymbolOccurrence") {} }; - // C++ wrapper for IfcRelVoidsElement - struct IfcRelVoidsElement : IfcRelConnects, ObjectHelper<IfcRelVoidsElement,2> { IfcRelVoidsElement() : Object("IfcRelVoidsElement") {} - Lazy< IfcElement > RelatingBuildingElement; - Lazy< IfcFeatureElementSubtraction > RelatedOpeningElement; + // C++ wrapper for IfcArbitraryClosedProfileDef + struct IfcArbitraryClosedProfileDef : IfcProfileDef, ObjectHelper<IfcArbitraryClosedProfileDef,1> { IfcArbitraryClosedProfileDef() : Object("IfcArbitraryClosedProfileDef") {} + Lazy< IfcCurve > OuterCurve; }; - // C++ wrapper for IfcWindow - struct IfcWindow : IfcBuildingElement, ObjectHelper<IfcWindow,2> { IfcWindow() : Object("IfcWindow") {} - Maybe< IfcPositiveLengthMeasure::Out > OverallHeight; - Maybe< IfcPositiveLengthMeasure::Out > OverallWidth; + // C++ wrapper for IfcArbitraryProfileDefWithVoids + struct IfcArbitraryProfileDefWithVoids : IfcArbitraryClosedProfileDef, ObjectHelper<IfcArbitraryProfileDefWithVoids,1> { IfcArbitraryProfileDefWithVoids() : Object("IfcArbitraryProfileDefWithVoids") {} + ListOf< Lazy< IfcCurve >, 1, 0 > InnerCurves; }; - // C++ wrapper for IfcProtectiveDeviceType - struct IfcProtectiveDeviceType : IfcFlowControllerType, ObjectHelper<IfcProtectiveDeviceType,1> { IfcProtectiveDeviceType() : Object("IfcProtectiveDeviceType") {} - IfcProtectiveDeviceTypeEnum::Out PredefinedType; + // C++ wrapper for IfcLine + struct IfcLine : IfcCurve, ObjectHelper<IfcLine,2> { IfcLine() : Object("IfcLine") {} + Lazy< IfcCartesianPoint > Pnt; + Lazy< IfcVector > Dir; }; - // C++ wrapper for IfcJunctionBoxType - struct IfcJunctionBoxType : IfcFlowFittingType, ObjectHelper<IfcJunctionBoxType,1> { IfcJunctionBoxType() : Object("IfcJunctionBoxType") {} - IfcJunctionBoxTypeEnum::Out PredefinedType; + // C++ wrapper for IfcFlowSegmentType + struct IfcFlowSegmentType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowSegmentType,0> { IfcFlowSegmentType() : Object("IfcFlowSegmentType") {} + }; - // C++ wrapper for IfcStructuralAnalysisModel - struct IfcStructuralAnalysisModel : IfcSystem, ObjectHelper<IfcStructuralAnalysisModel,4> { IfcStructuralAnalysisModel() : Object("IfcStructuralAnalysisModel") {} - IfcAnalysisModelTypeEnum::Out PredefinedType; - Maybe< Lazy< IfcAxis2Placement3D > > OrientationOf2DPlane; - Maybe< ListOf< Lazy< IfcStructuralLoadGroup >, 1, 0 > > LoadedBy; - Maybe< ListOf< Lazy< IfcStructuralResultGroup >, 1, 0 > > HasResults; + // C++ wrapper for IfcAirTerminalBoxType + struct IfcAirTerminalBoxType : IfcFlowControllerType, ObjectHelper<IfcAirTerminalBoxType,1> { IfcAirTerminalBoxType() : Object("IfcAirTerminalBoxType") {} + IfcAirTerminalBoxTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcAxis2Placement2D - struct IfcAxis2Placement2D : IfcPlacement, ObjectHelper<IfcAxis2Placement2D,1> { IfcAxis2Placement2D() : Object("IfcAxis2Placement2D") {} - Maybe< Lazy< IfcDirection > > RefDirection; + // C++ wrapper for IfcPropertySingleValue + struct IfcPropertySingleValue : IfcSimpleProperty, ObjectHelper<IfcPropertySingleValue,2> { IfcPropertySingleValue() : Object("IfcPropertySingleValue") {} + Maybe< IfcValue::Out > NominalValue; + Maybe< IfcUnit::Out > Unit; }; - // C++ wrapper for IfcSpaceType - struct IfcSpaceType : IfcSpatialStructureElementType, ObjectHelper<IfcSpaceType,1> { IfcSpaceType() : Object("IfcSpaceType") {} - IfcSpaceTypeEnum::Out PredefinedType; + // C++ wrapper for IfcAlarmType + struct IfcAlarmType : IfcDistributionControlElementType, ObjectHelper<IfcAlarmType,1> { IfcAlarmType() : Object("IfcAlarmType") {} + IfcAlarmTypeEnum::Out PredefinedType; }; // C++ wrapper for IfcEllipseProfileDef @@ -2434,112 +2586,101 @@ namespace IFC { IfcPositiveLengthMeasure::Out SemiAxis2; }; - // C++ wrapper for IfcDistributionFlowElement - struct IfcDistributionFlowElement : IfcDistributionElement, ObjectHelper<IfcDistributionFlowElement,0> { IfcDistributionFlowElement() : Object("IfcDistributionFlowElement") {} - + // C++ wrapper for IfcStair + struct IfcStair : IfcBuildingElement, ObjectHelper<IfcStair,1> { IfcStair() : Object("IfcStair") {} + IfcStairTypeEnum::Out ShapeType; }; - // C++ wrapper for IfcFlowMovingDevice - struct IfcFlowMovingDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowMovingDevice,0> { IfcFlowMovingDevice() : Object("IfcFlowMovingDevice") {} - + // C++ wrapper for IfcSurfaceStyleShading + struct IfcSurfaceStyleShading : ObjectHelper<IfcSurfaceStyleShading,1> { IfcSurfaceStyleShading() : Object("IfcSurfaceStyleShading") {} + Lazy< IfcColourRgb > SurfaceColour; }; - // C++ wrapper for IfcSurfaceStyleWithTextures - struct IfcSurfaceStyleWithTextures : ObjectHelper<IfcSurfaceStyleWithTextures,1> { IfcSurfaceStyleWithTextures() : Object("IfcSurfaceStyleWithTextures") {} - ListOf< Lazy< NotImplemented >, 1, 0 > Textures; + // C++ wrapper for IfcPumpType + struct IfcPumpType : IfcFlowMovingDeviceType, ObjectHelper<IfcPumpType,1> { IfcPumpType() : Object("IfcPumpType") {} + IfcPumpTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcGeometricSet - struct IfcGeometricSet : IfcGeometricRepresentationItem, ObjectHelper<IfcGeometricSet,1> { IfcGeometricSet() : Object("IfcGeometricSet") {} - ListOf< IfcGeometricSetSelect, 1, 0 >::Out Elements; + // C++ wrapper for IfcDefinedSymbol + struct IfcDefinedSymbol : IfcGeometricRepresentationItem, ObjectHelper<IfcDefinedSymbol,2> { IfcDefinedSymbol() : Object("IfcDefinedSymbol") {} + IfcDefinedSymbolSelect::Out Definition; + Lazy< IfcCartesianTransformationOperator2D > Target; }; - // C++ wrapper for IfcProjectOrder - struct IfcProjectOrder : IfcControl, ObjectHelper<IfcProjectOrder,3> { IfcProjectOrder() : Object("IfcProjectOrder") {} - IfcIdentifier::Out ID; - IfcProjectOrderTypeEnum::Out PredefinedType; - Maybe< IfcLabel::Out > Status; - }; + // C++ wrapper for IfcElementComponentType + struct IfcElementComponentType : IfcElementType, ObjectHelper<IfcElementComponentType,0> { IfcElementComponentType() : Object("IfcElementComponentType") {} - // C++ wrapper for IfcBSplineCurve - struct IfcBSplineCurve : IfcBoundedCurve, ObjectHelper<IfcBSplineCurve,5> { IfcBSplineCurve() : Object("IfcBSplineCurve") {} - INTEGER::Out Degree; - ListOf< Lazy< IfcCartesianPoint >, 2, 0 > ControlPointsList; - IfcBSplineCurveForm::Out CurveForm; - LOGICAL::Out ClosedCurve; - LOGICAL::Out SelfIntersect; }; - // C++ wrapper for IfcBezierCurve - struct IfcBezierCurve : IfcBSplineCurve, ObjectHelper<IfcBezierCurve,0> { IfcBezierCurve() : Object("IfcBezierCurve") {} + // C++ wrapper for IfcFastenerType + struct IfcFastenerType : IfcElementComponentType, ObjectHelper<IfcFastenerType,0> { IfcFastenerType() : Object("IfcFastenerType") {} }; - // C++ wrapper for IfcStructuralPointConnection - struct IfcStructuralPointConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralPointConnection,0> { IfcStructuralPointConnection() : Object("IfcStructuralPointConnection") {} + // C++ wrapper for IfcMechanicalFastenerType + struct IfcMechanicalFastenerType : IfcFastenerType, ObjectHelper<IfcMechanicalFastenerType,0> { IfcMechanicalFastenerType() : Object("IfcMechanicalFastenerType") {} }; - // C++ wrapper for IfcFlowController - struct IfcFlowController : IfcDistributionFlowElement, ObjectHelper<IfcFlowController,0> { IfcFlowController() : Object("IfcFlowController") {} + // C++ wrapper for IfcFlowFitting + struct IfcFlowFitting : IfcDistributionFlowElement, ObjectHelper<IfcFlowFitting,0> { IfcFlowFitting() : Object("IfcFlowFitting") {} }; - // C++ wrapper for IfcElectricDistributionPoint - struct IfcElectricDistributionPoint : IfcFlowController, ObjectHelper<IfcElectricDistributionPoint,2> { IfcElectricDistributionPoint() : Object("IfcElectricDistributionPoint") {} - IfcElectricDistributionPointFunctionEnum::Out DistributionPointFunction; - Maybe< IfcLabel::Out > UserDefinedFunction; + // C++ wrapper for IfcLightSourceDirectional + struct IfcLightSourceDirectional : IfcLightSource, ObjectHelper<IfcLightSourceDirectional,1> { IfcLightSourceDirectional() : Object("IfcLightSourceDirectional") {} + Lazy< IfcDirection > Orientation; }; - // C++ wrapper for IfcSite - struct IfcSite : IfcSpatialStructureElement, ObjectHelper<IfcSite,5> { IfcSite() : Object("IfcSite") {} - Maybe< IfcCompoundPlaneAngleMeasure::Out > RefLatitude; - Maybe< IfcCompoundPlaneAngleMeasure::Out > RefLongitude; - Maybe< IfcLengthMeasure::Out > RefElevation; - Maybe< IfcLabel::Out > LandTitleNumber; - Maybe< Lazy< NotImplemented > > SiteAddress; + // C++ wrapper for IfcSurfaceStyle + struct IfcSurfaceStyle : IfcPresentationStyle, ObjectHelper<IfcSurfaceStyle,2> { IfcSurfaceStyle() : Object("IfcSurfaceStyle") {} + IfcSurfaceSide::Out Side; + ListOf< IfcSurfaceStyleElementSelect, 1, 5 >::Out Styles; }; - // C++ wrapper for IfcOffsetCurve3D - struct IfcOffsetCurve3D : IfcCurve, ObjectHelper<IfcOffsetCurve3D,4> { IfcOffsetCurve3D() : Object("IfcOffsetCurve3D") {} - Lazy< IfcCurve > BasisCurve; - IfcLengthMeasure::Out Distance; - LOGICAL::Out SelfIntersect; - Lazy< IfcDirection > RefDirection; + // C++ wrapper for IfcAnnotationSurface + struct IfcAnnotationSurface : IfcGeometricRepresentationItem, ObjectHelper<IfcAnnotationSurface,2> { IfcAnnotationSurface() : Object("IfcAnnotationSurface") {} + Lazy< IfcGeometricRepresentationItem > Item; + Maybe< Lazy< NotImplemented > > TextureCoordinates; }; - // C++ wrapper for IfcVirtualElement - struct IfcVirtualElement : IfcElement, ObjectHelper<IfcVirtualElement,0> { IfcVirtualElement() : Object("IfcVirtualElement") {} + // C++ wrapper for IfcFlowController + struct IfcFlowController : IfcDistributionFlowElement, ObjectHelper<IfcFlowController,0> { IfcFlowController() : Object("IfcFlowController") {} }; - // C++ wrapper for IfcConstructionProductResource - struct IfcConstructionProductResource : IfcConstructionResource, ObjectHelper<IfcConstructionProductResource,0> { IfcConstructionProductResource() : Object("IfcConstructionProductResource") {} - + // C++ wrapper for IfcBuildingStorey + struct IfcBuildingStorey : IfcSpatialStructureElement, ObjectHelper<IfcBuildingStorey,1> { IfcBuildingStorey() : Object("IfcBuildingStorey") {} + Maybe< IfcLengthMeasure::Out > Elevation; }; - // C++ wrapper for IfcSurfaceCurveSweptAreaSolid - struct IfcSurfaceCurveSweptAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcSurfaceCurveSweptAreaSolid,4> { IfcSurfaceCurveSweptAreaSolid() : Object("IfcSurfaceCurveSweptAreaSolid") {} - Lazy< IfcCurve > Directrix; - IfcParameterValue::Out StartParam; - IfcParameterValue::Out EndParam; - Lazy< IfcSurface > ReferenceSurface; + // C++ wrapper for IfcWorkControl + struct IfcWorkControl : IfcControl, ObjectHelper<IfcWorkControl,10> { IfcWorkControl() : Object("IfcWorkControl") {} + IfcIdentifier::Out Identifier; + IfcDateTimeSelect::Out CreationDate; + Maybe< ListOf< Lazy< NotImplemented >, 1, 0 > > Creators; + Maybe< IfcLabel::Out > Purpose; + Maybe< IfcTimeMeasure::Out > Duration; + Maybe< IfcTimeMeasure::Out > TotalFloat; + IfcDateTimeSelect::Out StartTime; + Maybe< IfcDateTimeSelect::Out > FinishTime; + Maybe< IfcWorkControlTypeEnum::Out > WorkControlType; + Maybe< IfcLabel::Out > UserDefinedControlType; }; - // C++ wrapper for IfcCartesianTransformationOperator3D - struct IfcCartesianTransformationOperator3D : IfcCartesianTransformationOperator, ObjectHelper<IfcCartesianTransformationOperator3D,1> { IfcCartesianTransformationOperator3D() : Object("IfcCartesianTransformationOperator3D") {} - Maybe< Lazy< IfcDirection > > Axis3; - }; + // C++ wrapper for IfcWorkSchedule + struct IfcWorkSchedule : IfcWorkControl, ObjectHelper<IfcWorkSchedule,0> { IfcWorkSchedule() : Object("IfcWorkSchedule") {} - // C++ wrapper for IfcCartesianTransformationOperator3DnonUniform - struct IfcCartesianTransformationOperator3DnonUniform : IfcCartesianTransformationOperator3D, ObjectHelper<IfcCartesianTransformationOperator3DnonUniform,2> { IfcCartesianTransformationOperator3DnonUniform() : Object("IfcCartesianTransformationOperator3DnonUniform") {} - Maybe< REAL::Out > Scale2; - Maybe< REAL::Out > Scale3; }; - // C++ wrapper for IfcCrewResource - struct IfcCrewResource : IfcConstructionResource, ObjectHelper<IfcCrewResource,0> { IfcCrewResource() : Object("IfcCrewResource") {} + // C++ wrapper for IfcDuctSegmentType + struct IfcDuctSegmentType : IfcFlowSegmentType, ObjectHelper<IfcDuctSegmentType,1> { IfcDuctSegmentType() : Object("IfcDuctSegmentType") {} + IfcDuctSegmentTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcFace + struct IfcFace : IfcTopologicalRepresentationItem, ObjectHelper<IfcFace,1> { IfcFace() : Object("IfcFace") {} + ListOf< Lazy< IfcFaceBound >, 1, 0 > Bounds; }; // C++ wrapper for IfcStructuralSurfaceMember @@ -2548,655 +2689,650 @@ namespace IFC { Maybe< IfcPositiveLengthMeasure::Out > Thickness; }; - // C++ wrapper for Ifc2DCompositeCurve - struct Ifc2DCompositeCurve : IfcCompositeCurve, ObjectHelper<Ifc2DCompositeCurve,0> { Ifc2DCompositeCurve() : Object("Ifc2DCompositeCurve") {} - + // C++ wrapper for IfcStructuralSurfaceMemberVarying + struct IfcStructuralSurfaceMemberVarying : IfcStructuralSurfaceMember, ObjectHelper<IfcStructuralSurfaceMemberVarying,2> { IfcStructuralSurfaceMemberVarying() : Object("IfcStructuralSurfaceMemberVarying") {} + ListOf< IfcPositiveLengthMeasure, 2, 0 >::Out SubsequentThickness; + Lazy< NotImplemented > VaryingThicknessLocation; }; - // C++ wrapper for IfcRepresentationContext - struct IfcRepresentationContext : ObjectHelper<IfcRepresentationContext,2> { IfcRepresentationContext() : Object("IfcRepresentationContext") {} - Maybe< IfcLabel::Out > ContextIdentifier; - Maybe< IfcLabel::Out > ContextType; + // C++ wrapper for IfcFaceSurface + struct IfcFaceSurface : IfcFace, ObjectHelper<IfcFaceSurface,2> { IfcFaceSurface() : Object("IfcFaceSurface") {} + Lazy< IfcSurface > FaceSurface; + BOOLEAN::Out SameSense; }; - // C++ wrapper for IfcGeometricRepresentationContext - struct IfcGeometricRepresentationContext : IfcRepresentationContext, ObjectHelper<IfcGeometricRepresentationContext,4> { IfcGeometricRepresentationContext() : Object("IfcGeometricRepresentationContext") {} - IfcDimensionCount::Out CoordinateSpaceDimension; - Maybe< REAL::Out > Precision; - IfcAxis2Placement::Out WorldCoordinateSystem; - Maybe< Lazy< IfcDirection > > TrueNorth; + // C++ wrapper for IfcCostSchedule + struct IfcCostSchedule : IfcControl, ObjectHelper<IfcCostSchedule,8> { IfcCostSchedule() : Object("IfcCostSchedule") {} + Maybe< IfcActorSelect::Out > SubmittedBy; + Maybe< IfcActorSelect::Out > PreparedBy; + Maybe< IfcDateTimeSelect::Out > SubmittedOn; + Maybe< IfcLabel::Out > Status; + Maybe< ListOf< IfcActorSelect, 1, 0 >::Out > TargetUsers; + Maybe< IfcDateTimeSelect::Out > UpdateDate; + IfcIdentifier::Out ID; + IfcCostScheduleTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcFlowTreatmentDevice - struct IfcFlowTreatmentDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowTreatmentDevice,0> { IfcFlowTreatmentDevice() : Object("IfcFlowTreatmentDevice") {} - + // C++ wrapper for IfcPlanarExtent + struct IfcPlanarExtent : IfcGeometricRepresentationItem, ObjectHelper<IfcPlanarExtent,2> { IfcPlanarExtent() : Object("IfcPlanarExtent") {} + IfcLengthMeasure::Out SizeInX; + IfcLengthMeasure::Out SizeInY; }; - // C++ wrapper for IfcRightCircularCylinder - struct IfcRightCircularCylinder : IfcCsgPrimitive3D, ObjectHelper<IfcRightCircularCylinder,2> { IfcRightCircularCylinder() : Object("IfcRightCircularCylinder") {} - IfcPositiveLengthMeasure::Out Height; - IfcPositiveLengthMeasure::Out Radius; + // C++ wrapper for IfcPlanarBox + struct IfcPlanarBox : IfcPlanarExtent, ObjectHelper<IfcPlanarBox,1> { IfcPlanarBox() : Object("IfcPlanarBox") {} + IfcAxis2Placement::Out Placement; }; - // C++ wrapper for IfcWasteTerminalType - struct IfcWasteTerminalType : IfcFlowTerminalType, ObjectHelper<IfcWasteTerminalType,1> { IfcWasteTerminalType() : Object("IfcWasteTerminalType") {} - IfcWasteTerminalTypeEnum::Out PredefinedType; + // C++ wrapper for IfcColourSpecification + struct IfcColourSpecification : ObjectHelper<IfcColourSpecification,1> { IfcColourSpecification() : Object("IfcColourSpecification") {} + Maybe< IfcLabel::Out > Name; }; - // C++ wrapper for IfcBuildingElementComponent - struct IfcBuildingElementComponent : IfcBuildingElement, ObjectHelper<IfcBuildingElementComponent,0> { IfcBuildingElementComponent() : Object("IfcBuildingElementComponent") {} - + // C++ wrapper for IfcVector + struct IfcVector : IfcGeometricRepresentationItem, ObjectHelper<IfcVector,2> { IfcVector() : Object("IfcVector") {} + Lazy< IfcDirection > Orientation; + IfcLengthMeasure::Out Magnitude; }; - // C++ wrapper for IfcBuildingElementPart - struct IfcBuildingElementPart : IfcBuildingElementComponent, ObjectHelper<IfcBuildingElementPart,0> { IfcBuildingElementPart() : Object("IfcBuildingElementPart") {} + // C++ wrapper for IfcBeam + struct IfcBeam : IfcBuildingElement, ObjectHelper<IfcBeam,0> { IfcBeam() : Object("IfcBeam") {} }; - // C++ wrapper for IfcWall - struct IfcWall : IfcBuildingElement, ObjectHelper<IfcWall,0> { IfcWall() : Object("IfcWall") {} - + // C++ wrapper for IfcColourRgb + struct IfcColourRgb : IfcColourSpecification, ObjectHelper<IfcColourRgb,3> { IfcColourRgb() : Object("IfcColourRgb") {} + IfcNormalisedRatioMeasure::Out Red; + IfcNormalisedRatioMeasure::Out Green; + IfcNormalisedRatioMeasure::Out Blue; }; - // C++ wrapper for IfcWallStandardCase - struct IfcWallStandardCase : IfcWall, ObjectHelper<IfcWallStandardCase,0> { IfcWallStandardCase() : Object("IfcWallStandardCase") {} - + // C++ wrapper for IfcStructuralPlanarAction + struct IfcStructuralPlanarAction : IfcStructuralAction, ObjectHelper<IfcStructuralPlanarAction,1> { IfcStructuralPlanarAction() : Object("IfcStructuralPlanarAction") {} + IfcProjectedOrTrueLengthEnum::Out ProjectedOrTrue; }; - // C++ wrapper for IfcPath - struct IfcPath : IfcTopologicalRepresentationItem, ObjectHelper<IfcPath,1> { IfcPath() : Object("IfcPath") {} - ListOf< Lazy< IfcOrientedEdge >, 1, 0 > EdgeList; + // C++ wrapper for IfcStructuralPlanarActionVarying + struct IfcStructuralPlanarActionVarying : IfcStructuralPlanarAction, ObjectHelper<IfcStructuralPlanarActionVarying,2> { IfcStructuralPlanarActionVarying() : Object("IfcStructuralPlanarActionVarying") {} + Lazy< NotImplemented > VaryingAppliedLoadLocation; + ListOf< Lazy< NotImplemented >, 2, 0 > SubsequentAppliedLoads; }; - // C++ wrapper for IfcDefinedSymbol - struct IfcDefinedSymbol : IfcGeometricRepresentationItem, ObjectHelper<IfcDefinedSymbol,2> { IfcDefinedSymbol() : Object("IfcDefinedSymbol") {} - IfcDefinedSymbolSelect::Out Definition; - Lazy< IfcCartesianTransformationOperator2D > Target; + // C++ wrapper for IfcSite + struct IfcSite : IfcSpatialStructureElement, ObjectHelper<IfcSite,5> { IfcSite() : Object("IfcSite") {} + Maybe< IfcCompoundPlaneAngleMeasure::Out > RefLatitude; + Maybe< IfcCompoundPlaneAngleMeasure::Out > RefLongitude; + Maybe< IfcLengthMeasure::Out > RefElevation; + Maybe< IfcLabel::Out > LandTitleNumber; + Maybe< Lazy< NotImplemented > > SiteAddress; }; - // C++ wrapper for IfcStructuralSurfaceMemberVarying - struct IfcStructuralSurfaceMemberVarying : IfcStructuralSurfaceMember, ObjectHelper<IfcStructuralSurfaceMemberVarying,2> { IfcStructuralSurfaceMemberVarying() : Object("IfcStructuralSurfaceMemberVarying") {} - ListOf< IfcPositiveLengthMeasure, 2, 0 >::Out SubsequentThickness; - Lazy< NotImplemented > VaryingThicknessLocation; + // C++ wrapper for IfcDiscreteAccessoryType + struct IfcDiscreteAccessoryType : IfcElementComponentType, ObjectHelper<IfcDiscreteAccessoryType,0> { IfcDiscreteAccessoryType() : Object("IfcDiscreteAccessoryType") {} + }; - // C++ wrapper for IfcPoint - struct IfcPoint : IfcGeometricRepresentationItem, ObjectHelper<IfcPoint,0> { IfcPoint() : Object("IfcPoint") {} + // C++ wrapper for IfcVibrationIsolatorType + struct IfcVibrationIsolatorType : IfcDiscreteAccessoryType, ObjectHelper<IfcVibrationIsolatorType,1> { IfcVibrationIsolatorType() : Object("IfcVibrationIsolatorType") {} + IfcVibrationIsolatorTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcEvaporativeCoolerType + struct IfcEvaporativeCoolerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcEvaporativeCoolerType,1> { IfcEvaporativeCoolerType() : Object("IfcEvaporativeCoolerType") {} + IfcEvaporativeCoolerTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcSurfaceOfRevolution - struct IfcSurfaceOfRevolution : IfcSweptSurface, ObjectHelper<IfcSurfaceOfRevolution,1> { IfcSurfaceOfRevolution() : Object("IfcSurfaceOfRevolution") {} - Lazy< IfcAxis1Placement > AxisPosition; + // C++ wrapper for IfcDistributionChamberElementType + struct IfcDistributionChamberElementType : IfcDistributionFlowElementType, ObjectHelper<IfcDistributionChamberElementType,1> { IfcDistributionChamberElementType() : Object("IfcDistributionChamberElementType") {} + IfcDistributionChamberElementTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcFlowTerminal - struct IfcFlowTerminal : IfcDistributionFlowElement, ObjectHelper<IfcFlowTerminal,0> { IfcFlowTerminal() : Object("IfcFlowTerminal") {} + // C++ wrapper for IfcFeatureElementAddition + struct IfcFeatureElementAddition : IfcFeatureElement, ObjectHelper<IfcFeatureElementAddition,0> { IfcFeatureElementAddition() : Object("IfcFeatureElementAddition") {} }; - // C++ wrapper for IfcFurnishingElement - struct IfcFurnishingElement : IfcElement, ObjectHelper<IfcFurnishingElement,0> { IfcFurnishingElement() : Object("IfcFurnishingElement") {} + // C++ wrapper for IfcStructuredDimensionCallout + struct IfcStructuredDimensionCallout : IfcDraughtingCallout, ObjectHelper<IfcStructuredDimensionCallout,0> { IfcStructuredDimensionCallout() : Object("IfcStructuredDimensionCallout") {} }; - // C++ wrapper for IfcSurfaceStyleShading - struct IfcSurfaceStyleShading : ObjectHelper<IfcSurfaceStyleShading,1> { IfcSurfaceStyleShading() : Object("IfcSurfaceStyleShading") {} - Lazy< IfcColourRgb > SurfaceColour; + // C++ wrapper for IfcCoolingTowerType + struct IfcCoolingTowerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCoolingTowerType,1> { IfcCoolingTowerType() : Object("IfcCoolingTowerType") {} + IfcCoolingTowerTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcSurfaceStyleRendering - struct IfcSurfaceStyleRendering : IfcSurfaceStyleShading, ObjectHelper<IfcSurfaceStyleRendering,8> { IfcSurfaceStyleRendering() : Object("IfcSurfaceStyleRendering") {} - Maybe< IfcNormalisedRatioMeasure::Out > Transparency; - Maybe< IfcColourOrFactor::Out > DiffuseColour; - Maybe< IfcColourOrFactor::Out > TransmissionColour; - Maybe< IfcColourOrFactor::Out > DiffuseTransmissionColour; - Maybe< IfcColourOrFactor::Out > ReflectionColour; - Maybe< IfcColourOrFactor::Out > SpecularColour; - Maybe< IfcSpecularHighlightSelect::Out > SpecularHighlight; - IfcReflectanceMethodEnum::Out ReflectanceMethod; + // C++ wrapper for IfcCenterLineProfileDef + struct IfcCenterLineProfileDef : IfcArbitraryOpenProfileDef, ObjectHelper<IfcCenterLineProfileDef,1> { IfcCenterLineProfileDef() : Object("IfcCenterLineProfileDef") {} + IfcPositiveLengthMeasure::Out Thickness; }; - // C++ wrapper for IfcCircleHollowProfileDef - struct IfcCircleHollowProfileDef : IfcCircleProfileDef, ObjectHelper<IfcCircleHollowProfileDef,1> { IfcCircleHollowProfileDef() : Object("IfcCircleHollowProfileDef") {} - IfcPositiveLengthMeasure::Out WallThickness; + // C++ wrapper for IfcWindowStyle + struct IfcWindowStyle : IfcTypeProduct, ObjectHelper<IfcWindowStyle,4> { IfcWindowStyle() : Object("IfcWindowStyle") {} + IfcWindowStyleConstructionEnum::Out ConstructionType; + IfcWindowStyleOperationEnum::Out OperationType; + BOOLEAN::Out ParameterTakesPrecedence; + BOOLEAN::Out Sizeable; }; - // C++ wrapper for IfcFlowMovingDeviceType - struct IfcFlowMovingDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowMovingDeviceType,0> { IfcFlowMovingDeviceType() : Object("IfcFlowMovingDeviceType") {} - + // C++ wrapper for IfcLightSourceGoniometric + struct IfcLightSourceGoniometric : IfcLightSource, ObjectHelper<IfcLightSourceGoniometric,6> { IfcLightSourceGoniometric() : Object("IfcLightSourceGoniometric") {} + Lazy< IfcAxis2Placement3D > Position; + Maybe< Lazy< IfcColourRgb > > ColourAppearance; + IfcThermodynamicTemperatureMeasure::Out ColourTemperature; + IfcLuminousFluxMeasure::Out LuminousFlux; + IfcLightEmissionSourceEnum::Out LightEmissionSource; + IfcLightDistributionDataSourceSelect::Out LightDistributionDataSource; }; - // C++ wrapper for IfcFanType - struct IfcFanType : IfcFlowMovingDeviceType, ObjectHelper<IfcFanType,1> { IfcFanType() : Object("IfcFanType") {} - IfcFanTypeEnum::Out PredefinedType; + // C++ wrapper for IfcTransformerType + struct IfcTransformerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcTransformerType,1> { IfcTransformerType() : Object("IfcTransformerType") {} + IfcTransformerTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcStructuralPlanarActionVarying - struct IfcStructuralPlanarActionVarying : IfcStructuralPlanarAction, ObjectHelper<IfcStructuralPlanarActionVarying,2> { IfcStructuralPlanarActionVarying() : Object("IfcStructuralPlanarActionVarying") {} - Lazy< NotImplemented > VaryingAppliedLoadLocation; - ListOf< Lazy< NotImplemented >, 2, 0 > SubsequentAppliedLoads; + // C++ wrapper for IfcMemberType + struct IfcMemberType : IfcBuildingElementType, ObjectHelper<IfcMemberType,1> { IfcMemberType() : Object("IfcMemberType") {} + IfcMemberTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcProductRepresentation - struct IfcProductRepresentation : ObjectHelper<IfcProductRepresentation,3> { IfcProductRepresentation() : Object("IfcProductRepresentation") {} - Maybe< IfcLabel::Out > Name; - Maybe< IfcText::Out > Description; - ListOf< Lazy< IfcRepresentation >, 1, 0 > Representations; + // C++ wrapper for IfcSurfaceOfLinearExtrusion + struct IfcSurfaceOfLinearExtrusion : IfcSweptSurface, ObjectHelper<IfcSurfaceOfLinearExtrusion,2> { IfcSurfaceOfLinearExtrusion() : Object("IfcSurfaceOfLinearExtrusion") {} + Lazy< IfcDirection > ExtrudedDirection; + IfcLengthMeasure::Out Depth; }; - // C++ wrapper for IfcStackTerminalType - struct IfcStackTerminalType : IfcFlowTerminalType, ObjectHelper<IfcStackTerminalType,1> { IfcStackTerminalType() : Object("IfcStackTerminalType") {} - IfcStackTerminalTypeEnum::Out PredefinedType; + // C++ wrapper for IfcMotorConnectionType + struct IfcMotorConnectionType : IfcEnergyConversionDeviceType, ObjectHelper<IfcMotorConnectionType,1> { IfcMotorConnectionType() : Object("IfcMotorConnectionType") {} + IfcMotorConnectionTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcReinforcingElement - struct IfcReinforcingElement : IfcBuildingElementComponent, ObjectHelper<IfcReinforcingElement,1> { IfcReinforcingElement() : Object("IfcReinforcingElement") {} - Maybe< IfcLabel::Out > SteelGrade; - }; + // C++ wrapper for IfcFlowTreatmentDeviceType + struct IfcFlowTreatmentDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowTreatmentDeviceType,0> { IfcFlowTreatmentDeviceType() : Object("IfcFlowTreatmentDeviceType") {} - // C++ wrapper for IfcReinforcingMesh - struct IfcReinforcingMesh : IfcReinforcingElement, ObjectHelper<IfcReinforcingMesh,8> { IfcReinforcingMesh() : Object("IfcReinforcingMesh") {} - Maybe< IfcPositiveLengthMeasure::Out > MeshLength; - Maybe< IfcPositiveLengthMeasure::Out > MeshWidth; - IfcPositiveLengthMeasure::Out LongitudinalBarNominalDiameter; - IfcPositiveLengthMeasure::Out TransverseBarNominalDiameter; - IfcAreaMeasure::Out LongitudinalBarCrossSectionArea; - IfcAreaMeasure::Out TransverseBarCrossSectionArea; - IfcPositiveLengthMeasure::Out LongitudinalBarSpacing; - IfcPositiveLengthMeasure::Out TransverseBarSpacing; }; - // C++ wrapper for IfcOrderAction - struct IfcOrderAction : IfcTask, ObjectHelper<IfcOrderAction,1> { IfcOrderAction() : Object("IfcOrderAction") {} - IfcIdentifier::Out ActionID; + // C++ wrapper for IfcDuctSilencerType + struct IfcDuctSilencerType : IfcFlowTreatmentDeviceType, ObjectHelper<IfcDuctSilencerType,1> { IfcDuctSilencerType() : Object("IfcDuctSilencerType") {} + IfcDuctSilencerTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcLightSource - struct IfcLightSource : IfcGeometricRepresentationItem, ObjectHelper<IfcLightSource,4> { IfcLightSource() : Object("IfcLightSource") {} - Maybe< IfcLabel::Out > Name; - Lazy< IfcColourRgb > LightColour; - Maybe< IfcNormalisedRatioMeasure::Out > AmbientIntensity; - Maybe< IfcNormalisedRatioMeasure::Out > Intensity; - }; + // C++ wrapper for IfcFurnishingElementType + struct IfcFurnishingElementType : IfcElementType, ObjectHelper<IfcFurnishingElementType,0> { IfcFurnishingElementType() : Object("IfcFurnishingElementType") {} - // C++ wrapper for IfcLightSourceDirectional - struct IfcLightSourceDirectional : IfcLightSource, ObjectHelper<IfcLightSourceDirectional,1> { IfcLightSourceDirectional() : Object("IfcLightSourceDirectional") {} - Lazy< IfcDirection > Orientation; }; - // C++ wrapper for IfcLoop - struct IfcLoop : IfcTopologicalRepresentationItem, ObjectHelper<IfcLoop,0> { IfcLoop() : Object("IfcLoop") {} + // C++ wrapper for IfcSystemFurnitureElementType + struct IfcSystemFurnitureElementType : IfcFurnishingElementType, ObjectHelper<IfcSystemFurnitureElementType,0> { IfcSystemFurnitureElementType() : Object("IfcSystemFurnitureElementType") {} }; - // C++ wrapper for IfcVertexLoop - struct IfcVertexLoop : IfcLoop, ObjectHelper<IfcVertexLoop,1> { IfcVertexLoop() : Object("IfcVertexLoop") {} - Lazy< IfcVertex > LoopVertex; + // C++ wrapper for IfcWasteTerminalType + struct IfcWasteTerminalType : IfcFlowTerminalType, ObjectHelper<IfcWasteTerminalType,1> { IfcWasteTerminalType() : Object("IfcWasteTerminalType") {} + IfcWasteTerminalTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcChamferEdgeFeature - struct IfcChamferEdgeFeature : IfcEdgeFeature, ObjectHelper<IfcChamferEdgeFeature,2> { IfcChamferEdgeFeature() : Object("IfcChamferEdgeFeature") {} - Maybe< IfcPositiveLengthMeasure::Out > Width; - Maybe< IfcPositiveLengthMeasure::Out > Height; + // C++ wrapper for IfcBSplineCurve + struct IfcBSplineCurve : IfcBoundedCurve, ObjectHelper<IfcBSplineCurve,5> { IfcBSplineCurve() : Object("IfcBSplineCurve") {} + INTEGER::Out Degree; + ListOf< Lazy< IfcCartesianPoint >, 2, 0 > ControlPointsList; + IfcBSplineCurveForm::Out CurveForm; + LOGICAL::Out ClosedCurve; + LOGICAL::Out SelfIntersect; }; - // C++ wrapper for IfcElementComponentType - struct IfcElementComponentType : IfcElementType, ObjectHelper<IfcElementComponentType,0> { IfcElementComponentType() : Object("IfcElementComponentType") {} + // C++ wrapper for IfcBezierCurve + struct IfcBezierCurve : IfcBSplineCurve, ObjectHelper<IfcBezierCurve,0> { IfcBezierCurve() : Object("IfcBezierCurve") {} }; - // C++ wrapper for IfcFastenerType - struct IfcFastenerType : IfcElementComponentType, ObjectHelper<IfcFastenerType,0> { IfcFastenerType() : Object("IfcFastenerType") {} + // C++ wrapper for IfcActuatorType + struct IfcActuatorType : IfcDistributionControlElementType, ObjectHelper<IfcActuatorType,1> { IfcActuatorType() : Object("IfcActuatorType") {} + IfcActuatorTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcDistributionControlElement + struct IfcDistributionControlElement : IfcDistributionElement, ObjectHelper<IfcDistributionControlElement,1> { IfcDistributionControlElement() : Object("IfcDistributionControlElement") {} + Maybe< IfcIdentifier::Out > ControlElementId; }; - // C++ wrapper for IfcMechanicalFastenerType - struct IfcMechanicalFastenerType : IfcFastenerType, ObjectHelper<IfcMechanicalFastenerType,0> { IfcMechanicalFastenerType() : Object("IfcMechanicalFastenerType") {} + // C++ wrapper for IfcAnnotation + struct IfcAnnotation : IfcProduct, ObjectHelper<IfcAnnotation,0> { IfcAnnotation() : Object("IfcAnnotation") {} }; - // C++ wrapper for IfcScheduleTimeControl - struct IfcScheduleTimeControl : IfcControl, ObjectHelper<IfcScheduleTimeControl,18> { IfcScheduleTimeControl() : Object("IfcScheduleTimeControl") {} - Maybe< IfcDateTimeSelect::Out > ActualStart; - Maybe< IfcDateTimeSelect::Out > EarlyStart; - Maybe< IfcDateTimeSelect::Out > LateStart; - Maybe< IfcDateTimeSelect::Out > ScheduleStart; - Maybe< IfcDateTimeSelect::Out > ActualFinish; - Maybe< IfcDateTimeSelect::Out > EarlyFinish; - Maybe< IfcDateTimeSelect::Out > LateFinish; - Maybe< IfcDateTimeSelect::Out > ScheduleFinish; - Maybe< IfcTimeMeasure::Out > ScheduleDuration; - Maybe< IfcTimeMeasure::Out > ActualDuration; - Maybe< IfcTimeMeasure::Out > RemainingTime; - Maybe< IfcTimeMeasure::Out > FreeFloat; - Maybe< IfcTimeMeasure::Out > TotalFloat; - Maybe< BOOLEAN::Out > IsCritical; - Maybe< IfcDateTimeSelect::Out > StatusTime; - Maybe< IfcTimeMeasure::Out > StartFloat; - Maybe< IfcTimeMeasure::Out > FinishFloat; - Maybe< IfcPositiveRatioMeasure::Out > Completion; + // C++ wrapper for IfcShellBasedSurfaceModel + struct IfcShellBasedSurfaceModel : IfcGeometricRepresentationItem, ObjectHelper<IfcShellBasedSurfaceModel,1> { IfcShellBasedSurfaceModel() : Object("IfcShellBasedSurfaceModel") {} + ListOf< IfcShell, 1, 0 >::Out SbsmBoundary; }; - // C++ wrapper for IfcSurfaceStyle - struct IfcSurfaceStyle : IfcPresentationStyle, ObjectHelper<IfcSurfaceStyle,2> { IfcSurfaceStyle() : Object("IfcSurfaceStyle") {} - IfcSurfaceSide::Out Side; - ListOf< IfcSurfaceStyleElementSelect, 1, 5 >::Out Styles; + // C++ wrapper for IfcActionRequest + struct IfcActionRequest : IfcControl, ObjectHelper<IfcActionRequest,1> { IfcActionRequest() : Object("IfcActionRequest") {} + IfcIdentifier::Out RequestID; }; - // C++ wrapper for IfcOpenShell - struct IfcOpenShell : IfcConnectedFaceSet, ObjectHelper<IfcOpenShell,0> { IfcOpenShell() : Object("IfcOpenShell") {} + // C++ wrapper for IfcExtrudedAreaSolid + struct IfcExtrudedAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcExtrudedAreaSolid,2> { IfcExtrudedAreaSolid() : Object("IfcExtrudedAreaSolid") {} + Lazy< IfcDirection > ExtrudedDirection; + IfcPositiveLengthMeasure::Out Depth; + }; + + // C++ wrapper for IfcSystem + struct IfcSystem : IfcGroup, ObjectHelper<IfcSystem,0> { IfcSystem() : Object("IfcSystem") {} }; - // C++ wrapper for IfcSubContractResource - struct IfcSubContractResource : IfcConstructionResource, ObjectHelper<IfcSubContractResource,2> { IfcSubContractResource() : Object("IfcSubContractResource") {} - Maybe< IfcActorSelect::Out > SubContractor; - Maybe< IfcText::Out > JobDescription; + // C++ wrapper for IfcFillAreaStyleHatching + struct IfcFillAreaStyleHatching : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleHatching,5> { IfcFillAreaStyleHatching() : Object("IfcFillAreaStyleHatching") {} + Lazy< NotImplemented > HatchLineAppearance; + IfcHatchLineDistanceSelect::Out StartOfNextHatchLine; + Maybe< Lazy< IfcCartesianPoint > > PointOfReferenceHatchLine; + Maybe< Lazy< IfcCartesianPoint > > PatternStart; + IfcPlaneAngleMeasure::Out HatchLineAngle; }; - // C++ wrapper for IfcSweptDiskSolid - struct IfcSweptDiskSolid : IfcSolidModel, ObjectHelper<IfcSweptDiskSolid,5> { IfcSweptDiskSolid() : Object("IfcSweptDiskSolid") {} + // C++ wrapper for IfcRelVoidsElement + struct IfcRelVoidsElement : IfcRelConnects, ObjectHelper<IfcRelVoidsElement,2> { IfcRelVoidsElement() : Object("IfcRelVoidsElement") {} + Lazy< IfcElement > RelatingBuildingElement; + Lazy< IfcFeatureElementSubtraction > RelatedOpeningElement; + }; + + // C++ wrapper for IfcSurfaceCurveSweptAreaSolid + struct IfcSurfaceCurveSweptAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcSurfaceCurveSweptAreaSolid,4> { IfcSurfaceCurveSweptAreaSolid() : Object("IfcSurfaceCurveSweptAreaSolid") {} Lazy< IfcCurve > Directrix; - IfcPositiveLengthMeasure::Out Radius; - Maybe< IfcPositiveLengthMeasure::Out > InnerRadius; IfcParameterValue::Out StartParam; IfcParameterValue::Out EndParam; + Lazy< IfcSurface > ReferenceSurface; }; - // C++ wrapper for IfcCompositeProfileDef - struct IfcCompositeProfileDef : IfcProfileDef, ObjectHelper<IfcCompositeProfileDef,2> { IfcCompositeProfileDef() : Object("IfcCompositeProfileDef") {} - ListOf< Lazy< IfcProfileDef >, 2, 0 > Profiles; - Maybe< IfcLabel::Out > Label; + // C++ wrapper for IfcCartesianTransformationOperator3DnonUniform + struct IfcCartesianTransformationOperator3DnonUniform : IfcCartesianTransformationOperator3D, ObjectHelper<IfcCartesianTransformationOperator3DnonUniform,2> { IfcCartesianTransformationOperator3DnonUniform() : Object("IfcCartesianTransformationOperator3DnonUniform") {} + Maybe< REAL::Out > Scale2; + Maybe< REAL::Out > Scale3; }; - // C++ wrapper for IfcTankType - struct IfcTankType : IfcFlowStorageDeviceType, ObjectHelper<IfcTankType,1> { IfcTankType() : Object("IfcTankType") {} - IfcTankTypeEnum::Out PredefinedType; + // C++ wrapper for IfcCurtainWallType + struct IfcCurtainWallType : IfcBuildingElementType, ObjectHelper<IfcCurtainWallType,1> { IfcCurtainWallType() : Object("IfcCurtainWallType") {} + IfcCurtainWallTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcSphere - struct IfcSphere : IfcCsgPrimitive3D, ObjectHelper<IfcSphere,1> { IfcSphere() : Object("IfcSphere") {} - IfcPositiveLengthMeasure::Out Radius; + // C++ wrapper for IfcEquipmentStandard + struct IfcEquipmentStandard : IfcControl, ObjectHelper<IfcEquipmentStandard,0> { IfcEquipmentStandard() : Object("IfcEquipmentStandard") {} + }; - // C++ wrapper for IfcPolyLoop - struct IfcPolyLoop : IfcLoop, ObjectHelper<IfcPolyLoop,1> { IfcPolyLoop() : Object("IfcPolyLoop") {} - ListOf< Lazy< IfcCartesianPoint >, 3, 0 > Polygon; + // C++ wrapper for IfcFlowStorageDeviceType + struct IfcFlowStorageDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowStorageDeviceType,0> { IfcFlowStorageDeviceType() : Object("IfcFlowStorageDeviceType") {} + }; - // C++ wrapper for IfcCableCarrierFittingType - struct IfcCableCarrierFittingType : IfcFlowFittingType, ObjectHelper<IfcCableCarrierFittingType,1> { IfcCableCarrierFittingType() : Object("IfcCableCarrierFittingType") {} - IfcCableCarrierFittingTypeEnum::Out PredefinedType; + // C++ wrapper for IfcDiameterDimension + struct IfcDiameterDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcDiameterDimension,0> { IfcDiameterDimension() : Object("IfcDiameterDimension") {} + }; - // C++ wrapper for IfcHumidifierType - struct IfcHumidifierType : IfcEnergyConversionDeviceType, ObjectHelper<IfcHumidifierType,1> { IfcHumidifierType() : Object("IfcHumidifierType") {} - IfcHumidifierTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSwitchingDeviceType + struct IfcSwitchingDeviceType : IfcFlowControllerType, ObjectHelper<IfcSwitchingDeviceType,1> { IfcSwitchingDeviceType() : Object("IfcSwitchingDeviceType") {} + IfcSwitchingDeviceTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcPerformanceHistory - struct IfcPerformanceHistory : IfcControl, ObjectHelper<IfcPerformanceHistory,1> { IfcPerformanceHistory() : Object("IfcPerformanceHistory") {} - IfcLabel::Out LifeCyclePhase; + // C++ wrapper for IfcWindow + struct IfcWindow : IfcBuildingElement, ObjectHelper<IfcWindow,2> { IfcWindow() : Object("IfcWindow") {} + Maybe< IfcPositiveLengthMeasure::Out > OverallHeight; + Maybe< IfcPositiveLengthMeasure::Out > OverallWidth; }; - // C++ wrapper for IfcShapeModel - struct IfcShapeModel : IfcRepresentation, ObjectHelper<IfcShapeModel,0> { IfcShapeModel() : Object("IfcShapeModel") {} + // C++ wrapper for IfcFlowTreatmentDevice + struct IfcFlowTreatmentDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowTreatmentDevice,0> { IfcFlowTreatmentDevice() : Object("IfcFlowTreatmentDevice") {} }; - // C++ wrapper for IfcTopologyRepresentation - struct IfcTopologyRepresentation : IfcShapeModel, ObjectHelper<IfcTopologyRepresentation,0> { IfcTopologyRepresentation() : Object("IfcTopologyRepresentation") {} + // C++ wrapper for IfcChillerType + struct IfcChillerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcChillerType,1> { IfcChillerType() : Object("IfcChillerType") {} + IfcChillerTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcRectangleHollowProfileDef + struct IfcRectangleHollowProfileDef : IfcRectangleProfileDef, ObjectHelper<IfcRectangleHollowProfileDef,3> { IfcRectangleHollowProfileDef() : Object("IfcRectangleHollowProfileDef") {} + IfcPositiveLengthMeasure::Out WallThickness; + Maybe< IfcPositiveLengthMeasure::Out > InnerFilletRadius; + Maybe< IfcPositiveLengthMeasure::Out > OuterFilletRadius; }; - // C++ wrapper for IfcBuilding - struct IfcBuilding : IfcSpatialStructureElement, ObjectHelper<IfcBuilding,3> { IfcBuilding() : Object("IfcBuilding") {} - Maybe< IfcLengthMeasure::Out > ElevationOfRefHeight; - Maybe< IfcLengthMeasure::Out > ElevationOfTerrain; - Maybe< Lazy< NotImplemented > > BuildingAddress; + // C++ wrapper for IfcBoxedHalfSpace + struct IfcBoxedHalfSpace : IfcHalfSpaceSolid, ObjectHelper<IfcBoxedHalfSpace,1> { IfcBoxedHalfSpace() : Object("IfcBoxedHalfSpace") {} + Lazy< IfcBoundingBox > Enclosure; }; - // C++ wrapper for IfcRoundedRectangleProfileDef - struct IfcRoundedRectangleProfileDef : IfcRectangleProfileDef, ObjectHelper<IfcRoundedRectangleProfileDef,1> { IfcRoundedRectangleProfileDef() : Object("IfcRoundedRectangleProfileDef") {} - IfcPositiveLengthMeasure::Out RoundingRadius; + // C++ wrapper for IfcAxis2Placement2D + struct IfcAxis2Placement2D : IfcPlacement, ObjectHelper<IfcAxis2Placement2D,1> { IfcAxis2Placement2D() : Object("IfcAxis2Placement2D") {} + Maybe< Lazy< IfcDirection > > RefDirection; }; - // C++ wrapper for IfcStairFlight - struct IfcStairFlight : IfcBuildingElement, ObjectHelper<IfcStairFlight,4> { IfcStairFlight() : Object("IfcStairFlight") {} - Maybe< INTEGER::Out > NumberOfRiser; - Maybe< INTEGER::Out > NumberOfTreads; - Maybe< IfcPositiveLengthMeasure::Out > RiserHeight; - Maybe< IfcPositiveLengthMeasure::Out > TreadLength; + // C++ wrapper for IfcSpaceProgram + struct IfcSpaceProgram : IfcControl, ObjectHelper<IfcSpaceProgram,5> { IfcSpaceProgram() : Object("IfcSpaceProgram") {} + IfcIdentifier::Out SpaceProgramIdentifier; + Maybe< IfcAreaMeasure::Out > MaxRequiredArea; + Maybe< IfcAreaMeasure::Out > MinRequiredArea; + Maybe< Lazy< IfcSpatialStructureElement > > RequestedLocation; + IfcAreaMeasure::Out StandardRequiredArea; }; - // C++ wrapper for IfcDistributionChamberElement - struct IfcDistributionChamberElement : IfcDistributionFlowElement, ObjectHelper<IfcDistributionChamberElement,0> { IfcDistributionChamberElement() : Object("IfcDistributionChamberElement") {} + // C++ wrapper for IfcPoint + struct IfcPoint : IfcGeometricRepresentationItem, ObjectHelper<IfcPoint,0> { IfcPoint() : Object("IfcPoint") {} }; - // C++ wrapper for IfcShapeRepresentation - struct IfcShapeRepresentation : IfcShapeModel, ObjectHelper<IfcShapeRepresentation,0> { IfcShapeRepresentation() : Object("IfcShapeRepresentation") {} - + // C++ wrapper for IfcCartesianPoint + struct IfcCartesianPoint : IfcPoint, ObjectHelper<IfcCartesianPoint,1> { IfcCartesianPoint() : Object("IfcCartesianPoint") {} + ListOf< IfcLengthMeasure, 1, 3 >::Out Coordinates; }; - // C++ wrapper for IfcRampFlight - struct IfcRampFlight : IfcBuildingElement, ObjectHelper<IfcRampFlight,0> { IfcRampFlight() : Object("IfcRampFlight") {} + // C++ wrapper for IfcBoundedSurface + struct IfcBoundedSurface : IfcSurface, ObjectHelper<IfcBoundedSurface,0> { IfcBoundedSurface() : Object("IfcBoundedSurface") {} }; - // C++ wrapper for IfcBeamType - struct IfcBeamType : IfcBuildingElementType, ObjectHelper<IfcBeamType,1> { IfcBeamType() : Object("IfcBeamType") {} - IfcBeamTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcLoop + struct IfcLoop : IfcTopologicalRepresentationItem, ObjectHelper<IfcLoop,0> { IfcLoop() : Object("IfcLoop") {} - // C++ wrapper for IfcRelDecomposes - struct IfcRelDecomposes : IfcRelationship, ObjectHelper<IfcRelDecomposes,2> { IfcRelDecomposes() : Object("IfcRelDecomposes") {} - Lazy< IfcObjectDefinition > RelatingObject; - ListOf< Lazy< IfcObjectDefinition >, 1, 0 > RelatedObjects; }; - // C++ wrapper for IfcRoof - struct IfcRoof : IfcBuildingElement, ObjectHelper<IfcRoof,1> { IfcRoof() : Object("IfcRoof") {} - IfcRoofTypeEnum::Out ShapeType; + // C++ wrapper for IfcPolyLoop + struct IfcPolyLoop : IfcLoop, ObjectHelper<IfcPolyLoop,1> { IfcPolyLoop() : Object("IfcPolyLoop") {} + ListOf< Lazy< IfcCartesianPoint >, 3, 0 > Polygon; }; - // C++ wrapper for IfcFooting - struct IfcFooting : IfcBuildingElement, ObjectHelper<IfcFooting,1> { IfcFooting() : Object("IfcFooting") {} - IfcFootingTypeEnum::Out PredefinedType; + // C++ wrapper for IfcTerminatorSymbol + struct IfcTerminatorSymbol : IfcAnnotationSymbolOccurrence, ObjectHelper<IfcTerminatorSymbol,1> { IfcTerminatorSymbol() : Object("IfcTerminatorSymbol") {} + Lazy< IfcAnnotationCurveOccurrence > AnnotatedCurve; }; - // C++ wrapper for IfcLightSourceAmbient - struct IfcLightSourceAmbient : IfcLightSource, ObjectHelper<IfcLightSourceAmbient,0> { IfcLightSourceAmbient() : Object("IfcLightSourceAmbient") {} - + // C++ wrapper for IfcDimensionCurveTerminator + struct IfcDimensionCurveTerminator : IfcTerminatorSymbol, ObjectHelper<IfcDimensionCurveTerminator,1> { IfcDimensionCurveTerminator() : Object("IfcDimensionCurveTerminator") {} + IfcDimensionExtentUsage::Out Role; }; - // C++ wrapper for IfcWindowStyle - struct IfcWindowStyle : IfcTypeProduct, ObjectHelper<IfcWindowStyle,4> { IfcWindowStyle() : Object("IfcWindowStyle") {} - IfcWindowStyleConstructionEnum::Out ConstructionType; - IfcWindowStyleOperationEnum::Out OperationType; - BOOLEAN::Out ParameterTakesPrecedence; - BOOLEAN::Out Sizeable; + // C++ wrapper for IfcTrapeziumProfileDef + struct IfcTrapeziumProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcTrapeziumProfileDef,4> { IfcTrapeziumProfileDef() : Object("IfcTrapeziumProfileDef") {} + IfcPositiveLengthMeasure::Out BottomXDim; + IfcPositiveLengthMeasure::Out TopXDim; + IfcPositiveLengthMeasure::Out YDim; + IfcLengthMeasure::Out TopXOffset; }; - // C++ wrapper for IfcBuildingElementProxyType - struct IfcBuildingElementProxyType : IfcBuildingElementType, ObjectHelper<IfcBuildingElementProxyType,1> { IfcBuildingElementProxyType() : Object("IfcBuildingElementProxyType") {} - IfcBuildingElementProxyTypeEnum::Out PredefinedType; + // C++ wrapper for IfcRepresentationContext + struct IfcRepresentationContext : ObjectHelper<IfcRepresentationContext,2> { IfcRepresentationContext() : Object("IfcRepresentationContext") {} + Maybe< IfcLabel::Out > ContextIdentifier; + Maybe< IfcLabel::Out > ContextType; }; - // C++ wrapper for IfcAxis2Placement3D - struct IfcAxis2Placement3D : IfcPlacement, ObjectHelper<IfcAxis2Placement3D,2> { IfcAxis2Placement3D() : Object("IfcAxis2Placement3D") {} - Maybe< Lazy< IfcDirection > > Axis; - Maybe< Lazy< IfcDirection > > RefDirection; + // C++ wrapper for IfcGeometricRepresentationContext + struct IfcGeometricRepresentationContext : IfcRepresentationContext, ObjectHelper<IfcGeometricRepresentationContext,4> { IfcGeometricRepresentationContext() : Object("IfcGeometricRepresentationContext") {} + IfcDimensionCount::Out CoordinateSpaceDimension; + Maybe< REAL::Out > Precision; + IfcAxis2Placement::Out WorldCoordinateSystem; + Maybe< Lazy< IfcDirection > > TrueNorth; }; - // C++ wrapper for IfcEdgeCurve - struct IfcEdgeCurve : IfcEdge, ObjectHelper<IfcEdgeCurve,2> { IfcEdgeCurve() : Object("IfcEdgeCurve") {} - Lazy< IfcCurve > EdgeGeometry; - BOOLEAN::Out SameSense; + // C++ wrapper for IfcCurveBoundedPlane + struct IfcCurveBoundedPlane : IfcBoundedSurface, ObjectHelper<IfcCurveBoundedPlane,3> { IfcCurveBoundedPlane() : Object("IfcCurveBoundedPlane") {} + Lazy< IfcPlane > BasisSurface; + Lazy< IfcCurve > OuterBoundary; + ListOf< Lazy< IfcCurve >, 0, 0 > InnerBoundaries; }; - // C++ wrapper for IfcClosedShell - struct IfcClosedShell : IfcConnectedFaceSet, ObjectHelper<IfcClosedShell,0> { IfcClosedShell() : Object("IfcClosedShell") {} - + // C++ wrapper for IfcSIUnit + struct IfcSIUnit : IfcNamedUnit, ObjectHelper<IfcSIUnit,2> { IfcSIUnit() : Object("IfcSIUnit") {} + Maybe< IfcSIPrefix::Out > Prefix; + IfcSIUnitName::Out Name; }; - // C++ wrapper for IfcTendonAnchor - struct IfcTendonAnchor : IfcReinforcingElement, ObjectHelper<IfcTendonAnchor,0> { IfcTendonAnchor() : Object("IfcTendonAnchor") {} + // C++ wrapper for IfcStructuralReaction + struct IfcStructuralReaction : IfcStructuralActivity, ObjectHelper<IfcStructuralReaction,0> { IfcStructuralReaction() : Object("IfcStructuralReaction") {} }; - // C++ wrapper for IfcCondenserType - struct IfcCondenserType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCondenserType,1> { IfcCondenserType() : Object("IfcCondenserType") {} - IfcCondenserTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcStructuralPointReaction + struct IfcStructuralPointReaction : IfcStructuralReaction, ObjectHelper<IfcStructuralPointReaction,0> { IfcStructuralPointReaction() : Object("IfcStructuralPointReaction") {} - // C++ wrapper for IfcPipeSegmentType - struct IfcPipeSegmentType : IfcFlowSegmentType, ObjectHelper<IfcPipeSegmentType,1> { IfcPipeSegmentType() : Object("IfcPipeSegmentType") {} - IfcPipeSegmentTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcPointOnSurface - struct IfcPointOnSurface : IfcPoint, ObjectHelper<IfcPointOnSurface,3> { IfcPointOnSurface() : Object("IfcPointOnSurface") {} - Lazy< IfcSurface > BasisSurface; - IfcParameterValue::Out PointParameterU; - IfcParameterValue::Out PointParameterV; + // C++ wrapper for IfcAxis1Placement + struct IfcAxis1Placement : IfcPlacement, ObjectHelper<IfcAxis1Placement,1> { IfcAxis1Placement() : Object("IfcAxis1Placement") {} + Maybe< Lazy< IfcDirection > > Axis; }; - // C++ wrapper for IfcAsset - struct IfcAsset : IfcGroup, ObjectHelper<IfcAsset,9> { IfcAsset() : Object("IfcAsset") {} - IfcIdentifier::Out AssetID; - Lazy< NotImplemented > OriginalValue; - Lazy< NotImplemented > CurrentValue; - Lazy< NotImplemented > TotalReplacementCost; - IfcActorSelect::Out Owner; - IfcActorSelect::Out User; - Lazy< NotImplemented > ResponsiblePerson; - Lazy< NotImplemented > IncorporationDate; - Lazy< NotImplemented > DepreciatedValue; + // C++ wrapper for IfcElectricApplianceType + struct IfcElectricApplianceType : IfcFlowTerminalType, ObjectHelper<IfcElectricApplianceType,1> { IfcElectricApplianceType() : Object("IfcElectricApplianceType") {} + IfcElectricApplianceTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcLightSourcePositional - struct IfcLightSourcePositional : IfcLightSource, ObjectHelper<IfcLightSourcePositional,5> { IfcLightSourcePositional() : Object("IfcLightSourcePositional") {} - Lazy< IfcCartesianPoint > Position; - IfcPositiveLengthMeasure::Out Radius; - IfcReal::Out ConstantAttenuation; - IfcReal::Out DistanceAttenuation; - IfcReal::Out QuadricAttenuation; + // C++ wrapper for IfcSensorType + struct IfcSensorType : IfcDistributionControlElementType, ObjectHelper<IfcSensorType,1> { IfcSensorType() : Object("IfcSensorType") {} + IfcSensorTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcProjectionCurve - struct IfcProjectionCurve : IfcAnnotationCurveOccurrence, ObjectHelper<IfcProjectionCurve,0> { IfcProjectionCurve() : Object("IfcProjectionCurve") {} + // C++ wrapper for IfcFurnishingElement + struct IfcFurnishingElement : IfcElement, ObjectHelper<IfcFurnishingElement,0> { IfcFurnishingElement() : Object("IfcFurnishingElement") {} }; - // C++ wrapper for IfcFillAreaStyleTiles - struct IfcFillAreaStyleTiles : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleTiles,3> { IfcFillAreaStyleTiles() : Object("IfcFillAreaStyleTiles") {} - Lazy< IfcOneDirectionRepeatFactor > TilingPattern; - ListOf< IfcFillAreaStyleTileShapeSelect, 1, 0 >::Out Tiles; - IfcPositiveRatioMeasure::Out TilingScale; + // C++ wrapper for IfcProtectiveDeviceType + struct IfcProtectiveDeviceType : IfcFlowControllerType, ObjectHelper<IfcProtectiveDeviceType,1> { IfcProtectiveDeviceType() : Object("IfcProtectiveDeviceType") {} + IfcProtectiveDeviceTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcRelFillsElement - struct IfcRelFillsElement : IfcRelConnects, ObjectHelper<IfcRelFillsElement,2> { IfcRelFillsElement() : Object("IfcRelFillsElement") {} - Lazy< IfcOpeningElement > RelatingOpeningElement; - Lazy< IfcElement > RelatedBuildingElement; + // C++ wrapper for IfcZShapeProfileDef + struct IfcZShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcZShapeProfileDef,6> { IfcZShapeProfileDef() : Object("IfcZShapeProfileDef") {} + IfcPositiveLengthMeasure::Out Depth; + IfcPositiveLengthMeasure::Out FlangeWidth; + IfcPositiveLengthMeasure::Out WebThickness; + IfcPositiveLengthMeasure::Out FlangeThickness; + Maybe< IfcPositiveLengthMeasure::Out > FilletRadius; + Maybe< IfcPositiveLengthMeasure::Out > EdgeRadius; }; - // C++ wrapper for IfcElectricMotorType - struct IfcElectricMotorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcElectricMotorType,1> { IfcElectricMotorType() : Object("IfcElectricMotorType") {} - IfcElectricMotorTypeEnum::Out PredefinedType; + // C++ wrapper for IfcScheduleTimeControl + struct IfcScheduleTimeControl : IfcControl, ObjectHelper<IfcScheduleTimeControl,18> { IfcScheduleTimeControl() : Object("IfcScheduleTimeControl") {} + Maybe< IfcDateTimeSelect::Out > ActualStart; + Maybe< IfcDateTimeSelect::Out > EarlyStart; + Maybe< IfcDateTimeSelect::Out > LateStart; + Maybe< IfcDateTimeSelect::Out > ScheduleStart; + Maybe< IfcDateTimeSelect::Out > ActualFinish; + Maybe< IfcDateTimeSelect::Out > EarlyFinish; + Maybe< IfcDateTimeSelect::Out > LateFinish; + Maybe< IfcDateTimeSelect::Out > ScheduleFinish; + Maybe< IfcTimeMeasure::Out > ScheduleDuration; + Maybe< IfcTimeMeasure::Out > ActualDuration; + Maybe< IfcTimeMeasure::Out > RemainingTime; + Maybe< IfcTimeMeasure::Out > FreeFloat; + Maybe< IfcTimeMeasure::Out > TotalFloat; + Maybe< BOOLEAN::Out > IsCritical; + Maybe< IfcDateTimeSelect::Out > StatusTime; + Maybe< IfcTimeMeasure::Out > StartFloat; + Maybe< IfcTimeMeasure::Out > FinishFloat; + Maybe< IfcPositiveRatioMeasure::Out > Completion; }; - // C++ wrapper for IfcTendon - struct IfcTendon : IfcReinforcingElement, ObjectHelper<IfcTendon,8> { IfcTendon() : Object("IfcTendon") {} - IfcTendonTypeEnum::Out PredefinedType; - IfcPositiveLengthMeasure::Out NominalDiameter; - IfcAreaMeasure::Out CrossSectionArea; - Maybe< IfcForceMeasure::Out > TensionForce; - Maybe< IfcPressureMeasure::Out > PreStress; - Maybe< IfcNormalisedRatioMeasure::Out > FrictionCoefficient; - Maybe< IfcPositiveLengthMeasure::Out > AnchorageSlip; - Maybe< IfcPositiveLengthMeasure::Out > MinCurvatureRadius; + // C++ wrapper for IfcRepresentationMap + struct IfcRepresentationMap : ObjectHelper<IfcRepresentationMap,2> { IfcRepresentationMap() : Object("IfcRepresentationMap") {} + IfcAxis2Placement::Out MappingOrigin; + Lazy< IfcRepresentation > MappedRepresentation; }; - // C++ wrapper for IfcDistributionChamberElementType - struct IfcDistributionChamberElementType : IfcDistributionFlowElementType, ObjectHelper<IfcDistributionChamberElementType,1> { IfcDistributionChamberElementType() : Object("IfcDistributionChamberElementType") {} - IfcDistributionChamberElementTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcClosedShell + struct IfcClosedShell : IfcConnectedFaceSet, ObjectHelper<IfcClosedShell,0> { IfcClosedShell() : Object("IfcClosedShell") {} - // C++ wrapper for IfcMemberType - struct IfcMemberType : IfcBuildingElementType, ObjectHelper<IfcMemberType,1> { IfcMemberType() : Object("IfcMemberType") {} - IfcMemberTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcStructuralLinearAction - struct IfcStructuralLinearAction : IfcStructuralAction, ObjectHelper<IfcStructuralLinearAction,1> { IfcStructuralLinearAction() : Object("IfcStructuralLinearAction") {} - IfcProjectedOrTrueLengthEnum::Out ProjectedOrTrue; - }; + // C++ wrapper for IfcBuildingElementPart + struct IfcBuildingElementPart : IfcBuildingElementComponent, ObjectHelper<IfcBuildingElementPart,0> { IfcBuildingElementPart() : Object("IfcBuildingElementPart") {} - // C++ wrapper for IfcStructuralLinearActionVarying - struct IfcStructuralLinearActionVarying : IfcStructuralLinearAction, ObjectHelper<IfcStructuralLinearActionVarying,2> { IfcStructuralLinearActionVarying() : Object("IfcStructuralLinearActionVarying") {} - Lazy< NotImplemented > VaryingAppliedLoadLocation; - ListOf< Lazy< NotImplemented >, 1, 0 > SubsequentAppliedLoads; }; - // C++ wrapper for IfcProductDefinitionShape - struct IfcProductDefinitionShape : IfcProductRepresentation, ObjectHelper<IfcProductDefinitionShape,0> { IfcProductDefinitionShape() : Object("IfcProductDefinitionShape") {} - + // C++ wrapper for IfcBlock + struct IfcBlock : IfcCsgPrimitive3D, ObjectHelper<IfcBlock,3> { IfcBlock() : Object("IfcBlock") {} + IfcPositiveLengthMeasure::Out XLength; + IfcPositiveLengthMeasure::Out YLength; + IfcPositiveLengthMeasure::Out ZLength; }; - // C++ wrapper for IfcFastener - struct IfcFastener : IfcElementComponent, ObjectHelper<IfcFastener,0> { IfcFastener() : Object("IfcFastener") {} - + // C++ wrapper for IfcLightFixtureType + struct IfcLightFixtureType : IfcFlowTerminalType, ObjectHelper<IfcLightFixtureType,1> { IfcLightFixtureType() : Object("IfcLightFixtureType") {} + IfcLightFixtureTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcMechanicalFastener - struct IfcMechanicalFastener : IfcFastener, ObjectHelper<IfcMechanicalFastener,2> { IfcMechanicalFastener() : Object("IfcMechanicalFastener") {} - Maybe< IfcPositiveLengthMeasure::Out > NominalDiameter; - Maybe< IfcPositiveLengthMeasure::Out > NominalLength; - }; + // C++ wrapper for IfcOpeningElement + struct IfcOpeningElement : IfcFeatureElementSubtraction, ObjectHelper<IfcOpeningElement,0> { IfcOpeningElement() : Object("IfcOpeningElement") {} - // C++ wrapper for IfcEvaporatorType - struct IfcEvaporatorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcEvaporatorType,1> { IfcEvaporatorType() : Object("IfcEvaporatorType") {} - IfcEvaporatorTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcDiscreteAccessoryType - struct IfcDiscreteAccessoryType : IfcElementComponentType, ObjectHelper<IfcDiscreteAccessoryType,0> { IfcDiscreteAccessoryType() : Object("IfcDiscreteAccessoryType") {} - + // C++ wrapper for IfcLightSourceSpot + struct IfcLightSourceSpot : IfcLightSourcePositional, ObjectHelper<IfcLightSourceSpot,4> { IfcLightSourceSpot() : Object("IfcLightSourceSpot") {} + Lazy< IfcDirection > Orientation; + Maybe< IfcReal::Out > ConcentrationExponent; + IfcPositivePlaneAngleMeasure::Out SpreadAngle; + IfcPositivePlaneAngleMeasure::Out BeamWidthAngle; }; - // C++ wrapper for IfcStructuralCurveConnection - struct IfcStructuralCurveConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralCurveConnection,0> { IfcStructuralCurveConnection() : Object("IfcStructuralCurveConnection") {} + // C++ wrapper for IfcTendonAnchor + struct IfcTendonAnchor : IfcReinforcingElement, ObjectHelper<IfcTendonAnchor,0> { IfcTendonAnchor() : Object("IfcTendonAnchor") {} }; - // C++ wrapper for IfcProjectionElement - struct IfcProjectionElement : IfcFeatureElementAddition, ObjectHelper<IfcProjectionElement,0> { IfcProjectionElement() : Object("IfcProjectionElement") {} - + // C++ wrapper for IfcElectricFlowStorageDeviceType + struct IfcElectricFlowStorageDeviceType : IfcFlowStorageDeviceType, ObjectHelper<IfcElectricFlowStorageDeviceType,1> { IfcElectricFlowStorageDeviceType() : Object("IfcElectricFlowStorageDeviceType") {} + IfcElectricFlowStorageDeviceTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcCoveringType - struct IfcCoveringType : IfcBuildingElementType, ObjectHelper<IfcCoveringType,1> { IfcCoveringType() : Object("IfcCoveringType") {} - IfcCoveringTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSphere + struct IfcSphere : IfcCsgPrimitive3D, ObjectHelper<IfcSphere,1> { IfcSphere() : Object("IfcSphere") {} + IfcPositiveLengthMeasure::Out Radius; }; - // C++ wrapper for IfcPumpType - struct IfcPumpType : IfcFlowMovingDeviceType, ObjectHelper<IfcPumpType,1> { IfcPumpType() : Object("IfcPumpType") {} - IfcPumpTypeEnum::Out PredefinedType; + // C++ wrapper for IfcDamperType + struct IfcDamperType : IfcFlowControllerType, ObjectHelper<IfcDamperType,1> { IfcDamperType() : Object("IfcDamperType") {} + IfcDamperTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcPile - struct IfcPile : IfcBuildingElement, ObjectHelper<IfcPile,2> { IfcPile() : Object("IfcPile") {} - IfcPileTypeEnum::Out PredefinedType; - Maybe< IfcPileConstructionEnum::Out > ConstructionType; + // C++ wrapper for IfcProjectOrderRecord + struct IfcProjectOrderRecord : IfcControl, ObjectHelper<IfcProjectOrderRecord,2> { IfcProjectOrderRecord() : Object("IfcProjectOrderRecord") {} + ListOf< Lazy< NotImplemented >, 1, 0 > Records; + IfcProjectOrderRecordTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcUnitAssignment - struct IfcUnitAssignment : ObjectHelper<IfcUnitAssignment,1> { IfcUnitAssignment() : Object("IfcUnitAssignment") {} - ListOf< IfcUnit, 1, 0 >::Out Units; + // C++ wrapper for IfcDistributionChamberElement + struct IfcDistributionChamberElement : IfcDistributionFlowElement, ObjectHelper<IfcDistributionChamberElement,0> { IfcDistributionChamberElement() : Object("IfcDistributionChamberElement") {} + }; - // C++ wrapper for IfcBoundingBox - struct IfcBoundingBox : IfcGeometricRepresentationItem, ObjectHelper<IfcBoundingBox,4> { IfcBoundingBox() : Object("IfcBoundingBox") {} - Lazy< IfcCartesianPoint > Corner; - IfcPositiveLengthMeasure::Out XDim; - IfcPositiveLengthMeasure::Out YDim; - IfcPositiveLengthMeasure::Out ZDim; + // C++ wrapper for IfcMechanicalFastener + struct IfcMechanicalFastener : IfcFastener, ObjectHelper<IfcMechanicalFastener,2> { IfcMechanicalFastener() : Object("IfcMechanicalFastener") {} + Maybe< IfcPositiveLengthMeasure::Out > NominalDiameter; + Maybe< IfcPositiveLengthMeasure::Out > NominalLength; }; - // C++ wrapper for IfcShellBasedSurfaceModel - struct IfcShellBasedSurfaceModel : IfcGeometricRepresentationItem, ObjectHelper<IfcShellBasedSurfaceModel,1> { IfcShellBasedSurfaceModel() : Object("IfcShellBasedSurfaceModel") {} - ListOf< IfcShell, 1, 0 >::Out SbsmBoundary; + // C++ wrapper for IfcRectangularTrimmedSurface + struct IfcRectangularTrimmedSurface : IfcBoundedSurface, ObjectHelper<IfcRectangularTrimmedSurface,7> { IfcRectangularTrimmedSurface() : Object("IfcRectangularTrimmedSurface") {} + Lazy< IfcSurface > BasisSurface; + IfcParameterValue::Out U1; + IfcParameterValue::Out V1; + IfcParameterValue::Out U2; + IfcParameterValue::Out V2; + BOOLEAN::Out Usense; + BOOLEAN::Out Vsense; }; - // C++ wrapper for IfcFacetedBrep - struct IfcFacetedBrep : IfcManifoldSolidBrep, ObjectHelper<IfcFacetedBrep,0> { IfcFacetedBrep() : Object("IfcFacetedBrep") {} + // C++ wrapper for IfcZone + struct IfcZone : IfcGroup, ObjectHelper<IfcZone,0> { IfcZone() : Object("IfcZone") {} }; - // C++ wrapper for IfcTextLiteralWithExtent - struct IfcTextLiteralWithExtent : IfcTextLiteral, ObjectHelper<IfcTextLiteralWithExtent,2> { IfcTextLiteralWithExtent() : Object("IfcTextLiteralWithExtent") {} - Lazy< IfcPlanarExtent > Extent; - IfcBoxAlignment::Out BoxAlignment; + // C++ wrapper for IfcFanType + struct IfcFanType : IfcFlowMovingDeviceType, ObjectHelper<IfcFanType,1> { IfcFanType() : Object("IfcFanType") {} + IfcFanTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcElectricApplianceType - struct IfcElectricApplianceType : IfcFlowTerminalType, ObjectHelper<IfcElectricApplianceType,1> { IfcElectricApplianceType() : Object("IfcElectricApplianceType") {} - IfcElectricApplianceTypeEnum::Out PredefinedType; + // C++ wrapper for IfcGeometricSet + struct IfcGeometricSet : IfcGeometricRepresentationItem, ObjectHelper<IfcGeometricSet,1> { IfcGeometricSet() : Object("IfcGeometricSet") {} + ListOf< IfcGeometricSetSelect, 1, 0 >::Out Elements; }; - // C++ wrapper for IfcTrapeziumProfileDef - struct IfcTrapeziumProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcTrapeziumProfileDef,4> { IfcTrapeziumProfileDef() : Object("IfcTrapeziumProfileDef") {} - IfcPositiveLengthMeasure::Out BottomXDim; - IfcPositiveLengthMeasure::Out TopXDim; - IfcPositiveLengthMeasure::Out YDim; - IfcLengthMeasure::Out TopXOffset; + // C++ wrapper for IfcFillAreaStyleTiles + struct IfcFillAreaStyleTiles : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleTiles,3> { IfcFillAreaStyleTiles() : Object("IfcFillAreaStyleTiles") {} + Lazy< IfcOneDirectionRepeatFactor > TilingPattern; + ListOf< IfcFillAreaStyleTileShapeSelect, 1, 0 >::Out Tiles; + IfcPositiveRatioMeasure::Out TilingScale; }; - // C++ wrapper for IfcRelContainedInSpatialStructure - struct IfcRelContainedInSpatialStructure : IfcRelConnects, ObjectHelper<IfcRelContainedInSpatialStructure,2> { IfcRelContainedInSpatialStructure() : Object("IfcRelContainedInSpatialStructure") {} - ListOf< Lazy< IfcProduct >, 1, 0 > RelatedElements; - Lazy< IfcSpatialStructureElement > RelatingStructure; + // C++ wrapper for IfcCableSegmentType + struct IfcCableSegmentType : IfcFlowSegmentType, ObjectHelper<IfcCableSegmentType,1> { IfcCableSegmentType() : Object("IfcCableSegmentType") {} + IfcCableSegmentTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcEdgeLoop - struct IfcEdgeLoop : IfcLoop, ObjectHelper<IfcEdgeLoop,1> { IfcEdgeLoop() : Object("IfcEdgeLoop") {} - ListOf< Lazy< IfcOrientedEdge >, 1, 0 > EdgeList; + // C++ wrapper for IfcRelOverridesProperties + struct IfcRelOverridesProperties : IfcRelDefinesByProperties, ObjectHelper<IfcRelOverridesProperties,1> { IfcRelOverridesProperties() : Object("IfcRelOverridesProperties") {} + ListOf< Lazy< IfcProperty >, 1, 0 > OverridingProperties; }; - // C++ wrapper for IfcProject - struct IfcProject : IfcObject, ObjectHelper<IfcProject,4> { IfcProject() : Object("IfcProject") {} - Maybe< IfcLabel::Out > LongName; - Maybe< IfcLabel::Out > Phase; - ListOf< Lazy< IfcRepresentationContext >, 1, 0 > RepresentationContexts; - Lazy< IfcUnitAssignment > UnitsInContext; + // C++ wrapper for IfcMeasureWithUnit + struct IfcMeasureWithUnit : ObjectHelper<IfcMeasureWithUnit,2> { IfcMeasureWithUnit() : Object("IfcMeasureWithUnit") {} + IfcValue::Out ValueComponent; + IfcUnit::Out UnitComponent; }; - // C++ wrapper for IfcCartesianPoint - struct IfcCartesianPoint : IfcPoint, ObjectHelper<IfcCartesianPoint,1> { IfcCartesianPoint() : Object("IfcCartesianPoint") {} - ListOf< IfcLengthMeasure, 1, 3 >::Out Coordinates; + // C++ wrapper for IfcSlabType + struct IfcSlabType : IfcBuildingElementType, ObjectHelper<IfcSlabType,1> { IfcSlabType() : Object("IfcSlabType") {} + IfcSlabTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcCurveBoundedPlane - struct IfcCurveBoundedPlane : IfcBoundedSurface, ObjectHelper<IfcCurveBoundedPlane,3> { IfcCurveBoundedPlane() : Object("IfcCurveBoundedPlane") {} - Lazy< IfcPlane > BasisSurface; - Lazy< IfcCurve > OuterBoundary; - ListOf< Lazy< IfcCurve >, 0, 0 > InnerBoundaries; + // C++ wrapper for IfcServiceLife + struct IfcServiceLife : IfcControl, ObjectHelper<IfcServiceLife,2> { IfcServiceLife() : Object("IfcServiceLife") {} + IfcServiceLifeTypeEnum::Out ServiceLifeType; + IfcTimeMeasure::Out ServiceLifeDuration; }; - // C++ wrapper for IfcWallType - struct IfcWallType : IfcBuildingElementType, ObjectHelper<IfcWallType,1> { IfcWallType() : Object("IfcWallType") {} - IfcWallTypeEnum::Out PredefinedType; + // C++ wrapper for IfcFurnitureType + struct IfcFurnitureType : IfcFurnishingElementType, ObjectHelper<IfcFurnitureType,1> { IfcFurnitureType() : Object("IfcFurnitureType") {} + IfcAssemblyPlaceEnum::Out AssemblyPlace; }; - // C++ wrapper for IfcFillAreaStyleHatching - struct IfcFillAreaStyleHatching : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleHatching,5> { IfcFillAreaStyleHatching() : Object("IfcFillAreaStyleHatching") {} - Lazy< NotImplemented > HatchLineAppearance; - IfcHatchLineDistanceSelect::Out StartOfNextHatchLine; - Maybe< Lazy< IfcCartesianPoint > > PointOfReferenceHatchLine; - Maybe< Lazy< IfcCartesianPoint > > PatternStart; - IfcPlaneAngleMeasure::Out HatchLineAngle; + // C++ wrapper for IfcCostItem + struct IfcCostItem : IfcControl, ObjectHelper<IfcCostItem,0> { IfcCostItem() : Object("IfcCostItem") {} + }; - // C++ wrapper for IfcEquipmentStandard - struct IfcEquipmentStandard : IfcControl, ObjectHelper<IfcEquipmentStandard,0> { IfcEquipmentStandard() : Object("IfcEquipmentStandard") {} + // C++ wrapper for IfcReinforcingMesh + struct IfcReinforcingMesh : IfcReinforcingElement, ObjectHelper<IfcReinforcingMesh,8> { IfcReinforcingMesh() : Object("IfcReinforcingMesh") {} + Maybe< IfcPositiveLengthMeasure::Out > MeshLength; + Maybe< IfcPositiveLengthMeasure::Out > MeshWidth; + IfcPositiveLengthMeasure::Out LongitudinalBarNominalDiameter; + IfcPositiveLengthMeasure::Out TransverseBarNominalDiameter; + IfcAreaMeasure::Out LongitudinalBarCrossSectionArea; + IfcAreaMeasure::Out TransverseBarCrossSectionArea; + IfcPositiveLengthMeasure::Out LongitudinalBarSpacing; + IfcPositiveLengthMeasure::Out TransverseBarSpacing; + }; + // C++ wrapper for IfcFacetedBrepWithVoids + struct IfcFacetedBrepWithVoids : IfcManifoldSolidBrep, ObjectHelper<IfcFacetedBrepWithVoids,1> { IfcFacetedBrepWithVoids() : Object("IfcFacetedBrepWithVoids") {} + ListOf< Lazy< IfcClosedShell >, 1, 0 > Voids; }; - // C++ wrapper for IfcDiameterDimension - struct IfcDiameterDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcDiameterDimension,0> { IfcDiameterDimension() : Object("IfcDiameterDimension") {} + // C++ wrapper for IfcGasTerminalType + struct IfcGasTerminalType : IfcFlowTerminalType, ObjectHelper<IfcGasTerminalType,1> { IfcGasTerminalType() : Object("IfcGasTerminalType") {} + IfcGasTerminalTypeEnum::Out PredefinedType; + }; + // C++ wrapper for IfcPile + struct IfcPile : IfcBuildingElement, ObjectHelper<IfcPile,2> { IfcPile() : Object("IfcPile") {} + IfcPileTypeEnum::Out PredefinedType; + Maybe< IfcPileConstructionEnum::Out > ConstructionType; }; - // C++ wrapper for IfcStructuralLoadGroup - struct IfcStructuralLoadGroup : IfcGroup, ObjectHelper<IfcStructuralLoadGroup,5> { IfcStructuralLoadGroup() : Object("IfcStructuralLoadGroup") {} - IfcLoadGroupTypeEnum::Out PredefinedType; - IfcActionTypeEnum::Out ActionType; - IfcActionSourceTypeEnum::Out ActionSource; - Maybe< IfcPositiveRatioMeasure::Out > Coefficient; - Maybe< IfcLabel::Out > Purpose; + // C++ wrapper for IfcFillAreaStyleTileSymbolWithStyle + struct IfcFillAreaStyleTileSymbolWithStyle : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleTileSymbolWithStyle,1> { IfcFillAreaStyleTileSymbolWithStyle() : Object("IfcFillAreaStyleTileSymbolWithStyle") {} + Lazy< IfcAnnotationSymbolOccurrence > Symbol; }; // C++ wrapper for IfcConstructionMaterialResource @@ -3205,216 +3341,154 @@ namespace IFC { Maybe< IfcRatioMeasure::Out > UsageRatio; }; - // C++ wrapper for IfcRelAggregates - struct IfcRelAggregates : IfcRelDecomposes, ObjectHelper<IfcRelAggregates,0> { IfcRelAggregates() : Object("IfcRelAggregates") {} + // C++ wrapper for IfcAnnotationCurveOccurrence + struct IfcAnnotationCurveOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationCurveOccurrence,0> { IfcAnnotationCurveOccurrence() : Object("IfcAnnotationCurveOccurrence") {} }; - // C++ wrapper for IfcBoilerType - struct IfcBoilerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcBoilerType,1> { IfcBoilerType() : Object("IfcBoilerType") {} - IfcBoilerTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcDimensionCurve + struct IfcDimensionCurve : IfcAnnotationCurveOccurrence, ObjectHelper<IfcDimensionCurve,0> { IfcDimensionCurve() : Object("IfcDimensionCurve") {} - // C++ wrapper for IfcColourSpecification - struct IfcColourSpecification : ObjectHelper<IfcColourSpecification,1> { IfcColourSpecification() : Object("IfcColourSpecification") {} - Maybe< IfcLabel::Out > Name; }; - // C++ wrapper for IfcColourRgb - struct IfcColourRgb : IfcColourSpecification, ObjectHelper<IfcColourRgb,3> { IfcColourRgb() : Object("IfcColourRgb") {} - IfcNormalisedRatioMeasure::Out Red; - IfcNormalisedRatioMeasure::Out Green; - IfcNormalisedRatioMeasure::Out Blue; - }; + // C++ wrapper for IfcGeometricCurveSet + struct IfcGeometricCurveSet : IfcGeometricSet, ObjectHelper<IfcGeometricCurveSet,0> { IfcGeometricCurveSet() : Object("IfcGeometricCurveSet") {} - // C++ wrapper for IfcDoorStyle - struct IfcDoorStyle : IfcTypeProduct, ObjectHelper<IfcDoorStyle,4> { IfcDoorStyle() : Object("IfcDoorStyle") {} - IfcDoorStyleOperationEnum::Out OperationType; - IfcDoorStyleConstructionEnum::Out ConstructionType; - BOOLEAN::Out ParameterTakesPrecedence; - BOOLEAN::Out Sizeable; }; - // C++ wrapper for IfcDuctSilencerType - struct IfcDuctSilencerType : IfcFlowTreatmentDeviceType, ObjectHelper<IfcDuctSilencerType,1> { IfcDuctSilencerType() : Object("IfcDuctSilencerType") {} - IfcDuctSilencerTypeEnum::Out PredefinedType; + // C++ wrapper for IfcRelAggregates + struct IfcRelAggregates : IfcRelDecomposes, ObjectHelper<IfcRelAggregates,0> { IfcRelAggregates() : Object("IfcRelAggregates") {} + }; - // C++ wrapper for IfcLightSourceGoniometric - struct IfcLightSourceGoniometric : IfcLightSource, ObjectHelper<IfcLightSourceGoniometric,6> { IfcLightSourceGoniometric() : Object("IfcLightSourceGoniometric") {} - Lazy< IfcAxis2Placement3D > Position; - Maybe< Lazy< IfcColourRgb > > ColourAppearance; - IfcThermodynamicTemperatureMeasure::Out ColourTemperature; - IfcLuminousFluxMeasure::Out LuminousFlux; - IfcLightEmissionSourceEnum::Out LightEmissionSource; - IfcLightDistributionDataSourceSelect::Out LightDistributionDataSource; + // C++ wrapper for IfcFaceBasedSurfaceModel + struct IfcFaceBasedSurfaceModel : IfcGeometricRepresentationItem, ObjectHelper<IfcFaceBasedSurfaceModel,1> { IfcFaceBasedSurfaceModel() : Object("IfcFaceBasedSurfaceModel") {} + ListOf< Lazy< IfcConnectedFaceSet >, 1, 0 > FbsmFaces; }; - // C++ wrapper for IfcActuatorType - struct IfcActuatorType : IfcDistributionControlElementType, ObjectHelper<IfcActuatorType,1> { IfcActuatorType() : Object("IfcActuatorType") {} - IfcActuatorTypeEnum::Out PredefinedType; + // C++ wrapper for IfcEnergyConversionDevice + struct IfcEnergyConversionDevice : IfcDistributionFlowElement, ObjectHelper<IfcEnergyConversionDevice,0> { IfcEnergyConversionDevice() : Object("IfcEnergyConversionDevice") {} + }; - // C++ wrapper for IfcSensorType - struct IfcSensorType : IfcDistributionControlElementType, ObjectHelper<IfcSensorType,1> { IfcSensorType() : Object("IfcSensorType") {} - IfcSensorTypeEnum::Out PredefinedType; + // C++ wrapper for IfcRampFlight + struct IfcRampFlight : IfcBuildingElement, ObjectHelper<IfcRampFlight,0> { IfcRampFlight() : Object("IfcRampFlight") {} + }; - // C++ wrapper for IfcAirTerminalBoxType - struct IfcAirTerminalBoxType : IfcFlowControllerType, ObjectHelper<IfcAirTerminalBoxType,1> { IfcAirTerminalBoxType() : Object("IfcAirTerminalBoxType") {} - IfcAirTerminalBoxTypeEnum::Out PredefinedType; + // C++ wrapper for IfcVertexLoop + struct IfcVertexLoop : IfcLoop, ObjectHelper<IfcVertexLoop,1> { IfcVertexLoop() : Object("IfcVertexLoop") {} + Lazy< IfcVertex > LoopVertex; }; - // C++ wrapper for IfcAnnotationSurfaceOccurrence - struct IfcAnnotationSurfaceOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationSurfaceOccurrence,0> { IfcAnnotationSurfaceOccurrence() : Object("IfcAnnotationSurfaceOccurrence") {} + // C++ wrapper for IfcPlate + struct IfcPlate : IfcBuildingElement, ObjectHelper<IfcPlate,0> { IfcPlate() : Object("IfcPlate") {} }; - // C++ wrapper for IfcZShapeProfileDef - struct IfcZShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcZShapeProfileDef,6> { IfcZShapeProfileDef() : Object("IfcZShapeProfileDef") {} + // C++ wrapper for IfcUShapeProfileDef + struct IfcUShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcUShapeProfileDef,8> { IfcUShapeProfileDef() : Object("IfcUShapeProfileDef") {} IfcPositiveLengthMeasure::Out Depth; IfcPositiveLengthMeasure::Out FlangeWidth; IfcPositiveLengthMeasure::Out WebThickness; IfcPositiveLengthMeasure::Out FlangeThickness; Maybe< IfcPositiveLengthMeasure::Out > FilletRadius; Maybe< IfcPositiveLengthMeasure::Out > EdgeRadius; + Maybe< IfcPlaneAngleMeasure::Out > FlangeSlope; + Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX; }; - // C++ wrapper for IfcRationalBezierCurve - struct IfcRationalBezierCurve : IfcBezierCurve, ObjectHelper<IfcRationalBezierCurve,1> { IfcRationalBezierCurve() : Object("IfcRationalBezierCurve") {} - ListOf< REAL, 2, 0 >::Out WeightsData; - }; - - // C++ wrapper for IfcCartesianTransformationOperator2D - struct IfcCartesianTransformationOperator2D : IfcCartesianTransformationOperator, ObjectHelper<IfcCartesianTransformationOperator2D,0> { IfcCartesianTransformationOperator2D() : Object("IfcCartesianTransformationOperator2D") {} - - }; - - // C++ wrapper for IfcCartesianTransformationOperator2DnonUniform - struct IfcCartesianTransformationOperator2DnonUniform : IfcCartesianTransformationOperator2D, ObjectHelper<IfcCartesianTransformationOperator2DnonUniform,1> { IfcCartesianTransformationOperator2DnonUniform() : Object("IfcCartesianTransformationOperator2DnonUniform") {} - Maybe< REAL::Out > Scale2; - }; - - // C++ wrapper for IfcMove - struct IfcMove : IfcTask, ObjectHelper<IfcMove,3> { IfcMove() : Object("IfcMove") {} - Lazy< IfcSpatialStructureElement > MoveFrom; - Lazy< IfcSpatialStructureElement > MoveTo; - Maybe< ListOf< IfcText, 1, 0 >::Out > PunchList; - }; - - // C++ wrapper for IfcCableCarrierSegmentType - struct IfcCableCarrierSegmentType : IfcFlowSegmentType, ObjectHelper<IfcCableCarrierSegmentType,1> { IfcCableCarrierSegmentType() : Object("IfcCableCarrierSegmentType") {} - IfcCableCarrierSegmentTypeEnum::Out PredefinedType; + // C++ wrapper for IfcFaceBound + struct IfcFaceBound : IfcTopologicalRepresentationItem, ObjectHelper<IfcFaceBound,2> { IfcFaceBound() : Object("IfcFaceBound") {} + Lazy< IfcLoop > Bound; + BOOLEAN::Out Orientation; }; - // C++ wrapper for IfcElectricalElement - struct IfcElectricalElement : IfcElement, ObjectHelper<IfcElectricalElement,0> { IfcElectricalElement() : Object("IfcElectricalElement") {} - - }; + // C++ wrapper for IfcFaceOuterBound + struct IfcFaceOuterBound : IfcFaceBound, ObjectHelper<IfcFaceOuterBound,0> { IfcFaceOuterBound() : Object("IfcFaceOuterBound") {} - // C++ wrapper for IfcChillerType - struct IfcChillerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcChillerType,1> { IfcChillerType() : Object("IfcChillerType") {} - IfcChillerTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcReinforcingBar - struct IfcReinforcingBar : IfcReinforcingElement, ObjectHelper<IfcReinforcingBar,5> { IfcReinforcingBar() : Object("IfcReinforcingBar") {} - IfcPositiveLengthMeasure::Out NominalDiameter; - IfcAreaMeasure::Out CrossSectionArea; - Maybe< IfcPositiveLengthMeasure::Out > BarLength; - IfcReinforcingBarRoleEnum::Out BarRole; - Maybe< IfcReinforcingBarSurfaceEnum::Out > BarSurface; + // C++ wrapper for IfcOneDirectionRepeatFactor + struct IfcOneDirectionRepeatFactor : IfcGeometricRepresentationItem, ObjectHelper<IfcOneDirectionRepeatFactor,1> { IfcOneDirectionRepeatFactor() : Object("IfcOneDirectionRepeatFactor") {} + Lazy< IfcVector > RepeatFactor; }; - // C++ wrapper for IfcCShapeProfileDef - struct IfcCShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCShapeProfileDef,6> { IfcCShapeProfileDef() : Object("IfcCShapeProfileDef") {} - IfcPositiveLengthMeasure::Out Depth; - IfcPositiveLengthMeasure::Out Width; - IfcPositiveLengthMeasure::Out WallThickness; - IfcPositiveLengthMeasure::Out Girth; - Maybe< IfcPositiveLengthMeasure::Out > InternalFilletRadius; - Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX; + // C++ wrapper for IfcBoilerType + struct IfcBoilerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcBoilerType,1> { IfcBoilerType() : Object("IfcBoilerType") {} + IfcBoilerTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcPermit - struct IfcPermit : IfcControl, ObjectHelper<IfcPermit,1> { IfcPermit() : Object("IfcPermit") {} - IfcIdentifier::Out PermitID; - }; + // C++ wrapper for IfcConstructionEquipmentResource + struct IfcConstructionEquipmentResource : IfcConstructionResource, ObjectHelper<IfcConstructionEquipmentResource,0> { IfcConstructionEquipmentResource() : Object("IfcConstructionEquipmentResource") {} - // C++ wrapper for IfcSlabType - struct IfcSlabType : IfcBuildingElementType, ObjectHelper<IfcSlabType,1> { IfcSlabType() : Object("IfcSlabType") {} - IfcSlabTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcLampType - struct IfcLampType : IfcFlowTerminalType, ObjectHelper<IfcLampType,1> { IfcLampType() : Object("IfcLampType") {} - IfcLampTypeEnum::Out PredefinedType; + // C++ wrapper for IfcComplexProperty + struct IfcComplexProperty : IfcProperty, ObjectHelper<IfcComplexProperty,2> { IfcComplexProperty() : Object("IfcComplexProperty") {} + IfcIdentifier::Out UsageName; + ListOf< Lazy< IfcProperty >, 1, 0 > HasProperties; }; - // C++ wrapper for IfcPlanarExtent - struct IfcPlanarExtent : IfcGeometricRepresentationItem, ObjectHelper<IfcPlanarExtent,2> { IfcPlanarExtent() : Object("IfcPlanarExtent") {} - IfcLengthMeasure::Out SizeInX; - IfcLengthMeasure::Out SizeInY; + // C++ wrapper for IfcFooting + struct IfcFooting : IfcBuildingElement, ObjectHelper<IfcFooting,1> { IfcFooting() : Object("IfcFooting") {} + IfcFootingTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcAlarmType - struct IfcAlarmType : IfcDistributionControlElementType, ObjectHelper<IfcAlarmType,1> { IfcAlarmType() : Object("IfcAlarmType") {} - IfcAlarmTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcConstructionProductResource + struct IfcConstructionProductResource : IfcConstructionResource, ObjectHelper<IfcConstructionProductResource,0> { IfcConstructionProductResource() : Object("IfcConstructionProductResource") {} - // C++ wrapper for IfcElectricFlowStorageDeviceType - struct IfcElectricFlowStorageDeviceType : IfcFlowStorageDeviceType, ObjectHelper<IfcElectricFlowStorageDeviceType,1> { IfcElectricFlowStorageDeviceType() : Object("IfcElectricFlowStorageDeviceType") {} - IfcElectricFlowStorageDeviceTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcEquipmentElement - struct IfcEquipmentElement : IfcElement, ObjectHelper<IfcEquipmentElement,0> { IfcEquipmentElement() : Object("IfcEquipmentElement") {} - + // C++ wrapper for IfcDerivedProfileDef + struct IfcDerivedProfileDef : IfcProfileDef, ObjectHelper<IfcDerivedProfileDef,3> { IfcDerivedProfileDef() : Object("IfcDerivedProfileDef") {} + Lazy< IfcProfileDef > ParentProfile; + Lazy< IfcCartesianTransformationOperator2D > Operator; + Maybe< IfcLabel::Out > Label; }; - // C++ wrapper for IfcLightFixtureType - struct IfcLightFixtureType : IfcFlowTerminalType, ObjectHelper<IfcLightFixtureType,1> { IfcLightFixtureType() : Object("IfcLightFixtureType") {} - IfcLightFixtureTypeEnum::Out PredefinedType; + // C++ wrapper for IfcPropertyTableValue + struct IfcPropertyTableValue : IfcSimpleProperty, ObjectHelper<IfcPropertyTableValue,5> { IfcPropertyTableValue() : Object("IfcPropertyTableValue") {} + ListOf< IfcValue, 1, 0 >::Out DefiningValues; + ListOf< IfcValue, 1, 0 >::Out DefinedValues; + Maybe< IfcText::Out > Expression; + Maybe< IfcUnit::Out > DefiningUnit; + Maybe< IfcUnit::Out > DefinedUnit; }; - // C++ wrapper for IfcCurtainWall - struct IfcCurtainWall : IfcBuildingElement, ObjectHelper<IfcCurtainWall,0> { IfcCurtainWall() : Object("IfcCurtainWall") {} - + // C++ wrapper for IfcFlowMeterType + struct IfcFlowMeterType : IfcFlowControllerType, ObjectHelper<IfcFlowMeterType,1> { IfcFlowMeterType() : Object("IfcFlowMeterType") {} + IfcFlowMeterTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcSlab - struct IfcSlab : IfcBuildingElement, ObjectHelper<IfcSlab,1> { IfcSlab() : Object("IfcSlab") {} - Maybe< IfcSlabTypeEnum::Out > PredefinedType; + // C++ wrapper for IfcDoorStyle + struct IfcDoorStyle : IfcTypeProduct, ObjectHelper<IfcDoorStyle,4> { IfcDoorStyle() : Object("IfcDoorStyle") {} + IfcDoorStyleOperationEnum::Out OperationType; + IfcDoorStyleConstructionEnum::Out ConstructionType; + BOOLEAN::Out ParameterTakesPrecedence; + BOOLEAN::Out Sizeable; }; - // C++ wrapper for IfcCurtainWallType - struct IfcCurtainWallType : IfcBuildingElementType, ObjectHelper<IfcCurtainWallType,1> { IfcCurtainWallType() : Object("IfcCurtainWallType") {} - IfcCurtainWallTypeEnum::Out PredefinedType; + // C++ wrapper for IfcUnitAssignment + struct IfcUnitAssignment : ObjectHelper<IfcUnitAssignment,1> { IfcUnitAssignment() : Object("IfcUnitAssignment") {} + ListOf< IfcUnit, 1, 0 >::Out Units; }; - // C++ wrapper for IfcOutletType - struct IfcOutletType : IfcFlowTerminalType, ObjectHelper<IfcOutletType,1> { IfcOutletType() : Object("IfcOutletType") {} - IfcOutletTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcFlowTerminal + struct IfcFlowTerminal : IfcDistributionFlowElement, ObjectHelper<IfcFlowTerminal,0> { IfcFlowTerminal() : Object("IfcFlowTerminal") {} - // C++ wrapper for IfcCompressorType - struct IfcCompressorType : IfcFlowMovingDeviceType, ObjectHelper<IfcCompressorType,1> { IfcCompressorType() : Object("IfcCompressorType") {} - IfcCompressorTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcCraneRailAShapeProfileDef - struct IfcCraneRailAShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCraneRailAShapeProfileDef,12> { IfcCraneRailAShapeProfileDef() : Object("IfcCraneRailAShapeProfileDef") {} + // C++ wrapper for IfcCraneRailFShapeProfileDef + struct IfcCraneRailFShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCraneRailFShapeProfileDef,9> { IfcCraneRailFShapeProfileDef() : Object("IfcCraneRailFShapeProfileDef") {} IfcPositiveLengthMeasure::Out OverallHeight; - IfcPositiveLengthMeasure::Out BaseWidth2; - Maybe< IfcPositiveLengthMeasure::Out > Radius; IfcPositiveLengthMeasure::Out HeadWidth; + Maybe< IfcPositiveLengthMeasure::Out > Radius; IfcPositiveLengthMeasure::Out HeadDepth2; IfcPositiveLengthMeasure::Out HeadDepth3; IfcPositiveLengthMeasure::Out WebThickness; - IfcPositiveLengthMeasure::Out BaseWidth4; IfcPositiveLengthMeasure::Out BaseDepth1; IfcPositiveLengthMeasure::Out BaseDepth2; - IfcPositiveLengthMeasure::Out BaseDepth3; Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; }; @@ -3423,253 +3497,236 @@ namespace IFC { }; - // C++ wrapper for IfcSectionedSpine - struct IfcSectionedSpine : IfcGeometricRepresentationItem, ObjectHelper<IfcSectionedSpine,3> { IfcSectionedSpine() : Object("IfcSectionedSpine") {} - Lazy< IfcCompositeCurve > SpineCurve; - ListOf< Lazy< IfcProfileDef >, 2, 0 > CrossSections; - ListOf< Lazy< IfcAxis2Placement3D >, 2, 0 > CrossSectionPositions; - }; - - // C++ wrapper for IfcElectricTimeControlType - struct IfcElectricTimeControlType : IfcFlowControllerType, ObjectHelper<IfcElectricTimeControlType,1> { IfcElectricTimeControlType() : Object("IfcElectricTimeControlType") {} - IfcElectricTimeControlTypeEnum::Out PredefinedType; + // C++ wrapper for IfcElementQuantity + struct IfcElementQuantity : IfcPropertySetDefinition, ObjectHelper<IfcElementQuantity,2> { IfcElementQuantity() : Object("IfcElementQuantity") {} + Maybe< IfcLabel::Out > MethodOfMeasurement; + ListOf< Lazy< NotImplemented >, 1, 0 > Quantities; }; - // C++ wrapper for IfcFaceSurface - struct IfcFaceSurface : IfcFace, ObjectHelper<IfcFaceSurface,2> { IfcFaceSurface() : Object("IfcFaceSurface") {} - Lazy< IfcSurface > FaceSurface; - BOOLEAN::Out SameSense; - }; + // C++ wrapper for IfcCurtainWall + struct IfcCurtainWall : IfcBuildingElement, ObjectHelper<IfcCurtainWall,0> { IfcCurtainWall() : Object("IfcCurtainWall") {} - // C++ wrapper for IfcMotorConnectionType - struct IfcMotorConnectionType : IfcEnergyConversionDeviceType, ObjectHelper<IfcMotorConnectionType,1> { IfcMotorConnectionType() : Object("IfcMotorConnectionType") {} - IfcMotorConnectionTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcFlowFitting - struct IfcFlowFitting : IfcDistributionFlowElement, ObjectHelper<IfcFlowFitting,0> { IfcFlowFitting() : Object("IfcFlowFitting") {} + // C++ wrapper for IfcDiscreteAccessory + struct IfcDiscreteAccessory : IfcElementComponent, ObjectHelper<IfcDiscreteAccessory,0> { IfcDiscreteAccessory() : Object("IfcDiscreteAccessory") {} }; - // C++ wrapper for IfcPointOnCurve - struct IfcPointOnCurve : IfcPoint, ObjectHelper<IfcPointOnCurve,2> { IfcPointOnCurve() : Object("IfcPointOnCurve") {} - Lazy< IfcCurve > BasisCurve; - IfcParameterValue::Out PointParameter; + // C++ wrapper for IfcGrid + struct IfcGrid : IfcProduct, ObjectHelper<IfcGrid,3> { IfcGrid() : Object("IfcGrid") {} + ListOf< Lazy< NotImplemented >, 1, 0 > UAxes; + ListOf< Lazy< NotImplemented >, 1, 0 > VAxes; + Maybe< ListOf< Lazy< NotImplemented >, 1, 0 > > WAxes; }; - // C++ wrapper for IfcTransportElementType - struct IfcTransportElementType : IfcElementType, ObjectHelper<IfcTransportElementType,1> { IfcTransportElementType() : Object("IfcTransportElementType") {} - IfcTransportElementTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSanitaryTerminalType + struct IfcSanitaryTerminalType : IfcFlowTerminalType, ObjectHelper<IfcSanitaryTerminalType,1> { IfcSanitaryTerminalType() : Object("IfcSanitaryTerminalType") {} + IfcSanitaryTerminalTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcCableSegmentType - struct IfcCableSegmentType : IfcFlowSegmentType, ObjectHelper<IfcCableSegmentType,1> { IfcCableSegmentType() : Object("IfcCableSegmentType") {} - IfcCableSegmentTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSubedge + struct IfcSubedge : IfcEdge, ObjectHelper<IfcSubedge,1> { IfcSubedge() : Object("IfcSubedge") {} + Lazy< IfcEdge > ParentEdge; }; - // C++ wrapper for IfcAnnotationSurface - struct IfcAnnotationSurface : IfcGeometricRepresentationItem, ObjectHelper<IfcAnnotationSurface,2> { IfcAnnotationSurface() : Object("IfcAnnotationSurface") {} - Lazy< IfcGeometricRepresentationItem > Item; - Maybe< Lazy< NotImplemented > > TextureCoordinates; + // C++ wrapper for IfcFilterType + struct IfcFilterType : IfcFlowTreatmentDeviceType, ObjectHelper<IfcFilterType,1> { IfcFilterType() : Object("IfcFilterType") {} + IfcFilterTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcCompositeCurveSegment - struct IfcCompositeCurveSegment : IfcGeometricRepresentationItem, ObjectHelper<IfcCompositeCurveSegment,3> { IfcCompositeCurveSegment() : Object("IfcCompositeCurveSegment") {} - IfcTransitionCode::Out Transition; - BOOLEAN::Out SameSense; - Lazy< IfcCurve > ParentCurve; + // C++ wrapper for IfcTendon + struct IfcTendon : IfcReinforcingElement, ObjectHelper<IfcTendon,8> { IfcTendon() : Object("IfcTendon") {} + IfcTendonTypeEnum::Out PredefinedType; + IfcPositiveLengthMeasure::Out NominalDiameter; + IfcAreaMeasure::Out CrossSectionArea; + Maybe< IfcForceMeasure::Out > TensionForce; + Maybe< IfcPressureMeasure::Out > PreStress; + Maybe< IfcNormalisedRatioMeasure::Out > FrictionCoefficient; + Maybe< IfcPositiveLengthMeasure::Out > AnchorageSlip; + Maybe< IfcPositiveLengthMeasure::Out > MinCurvatureRadius; }; - // C++ wrapper for IfcServiceLife - struct IfcServiceLife : IfcControl, ObjectHelper<IfcServiceLife,2> { IfcServiceLife() : Object("IfcServiceLife") {} - IfcServiceLifeTypeEnum::Out ServiceLifeType; - IfcTimeMeasure::Out ServiceLifeDuration; + // C++ wrapper for IfcStructuralLoadGroup + struct IfcStructuralLoadGroup : IfcGroup, ObjectHelper<IfcStructuralLoadGroup,5> { IfcStructuralLoadGroup() : Object("IfcStructuralLoadGroup") {} + IfcLoadGroupTypeEnum::Out PredefinedType; + IfcActionTypeEnum::Out ActionType; + IfcActionSourceTypeEnum::Out ActionSource; + Maybe< IfcPositiveRatioMeasure::Out > Coefficient; + Maybe< IfcLabel::Out > Purpose; }; - // C++ wrapper for IfcPlateType - struct IfcPlateType : IfcBuildingElementType, ObjectHelper<IfcPlateType,1> { IfcPlateType() : Object("IfcPlateType") {} - IfcPlateTypeEnum::Out PredefinedType; + // C++ wrapper for IfcPresentationStyleAssignment + struct IfcPresentationStyleAssignment : ObjectHelper<IfcPresentationStyleAssignment,1> { IfcPresentationStyleAssignment() : Object("IfcPresentationStyleAssignment") {} + ListOf< IfcPresentationStyleSelect, 1, 0 >::Out Styles; }; - // C++ wrapper for IfcVibrationIsolatorType - struct IfcVibrationIsolatorType : IfcDiscreteAccessoryType, ObjectHelper<IfcVibrationIsolatorType,1> { IfcVibrationIsolatorType() : Object("IfcVibrationIsolatorType") {} - IfcVibrationIsolatorTypeEnum::Out PredefinedType; + // C++ wrapper for IfcStructuralCurveMember + struct IfcStructuralCurveMember : IfcStructuralMember, ObjectHelper<IfcStructuralCurveMember,1> { IfcStructuralCurveMember() : Object("IfcStructuralCurveMember") {} + IfcStructuralCurveTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcTrimmedCurve - struct IfcTrimmedCurve : IfcBoundedCurve, ObjectHelper<IfcTrimmedCurve,5> { IfcTrimmedCurve() : Object("IfcTrimmedCurve") {} - Lazy< IfcCurve > BasisCurve; - ListOf< IfcTrimmingSelect, 1, 2 >::Out Trim1; - ListOf< IfcTrimmingSelect, 1, 2 >::Out Trim2; - BOOLEAN::Out SenseAgreement; - IfcTrimmingPreference::Out MasterRepresentation; - }; + // C++ wrapper for IfcLightSourceAmbient + struct IfcLightSourceAmbient : IfcLightSource, ObjectHelper<IfcLightSourceAmbient,0> { IfcLightSourceAmbient() : Object("IfcLightSourceAmbient") {} - // C++ wrapper for IfcMappedItem - struct IfcMappedItem : IfcRepresentationItem, ObjectHelper<IfcMappedItem,2> { IfcMappedItem() : Object("IfcMappedItem") {} - Lazy< IfcRepresentationMap > MappingSource; - Lazy< IfcCartesianTransformationOperator > MappingTarget; }; - // C++ wrapper for IfcDirection - struct IfcDirection : IfcGeometricRepresentationItem, ObjectHelper<IfcDirection,1> { IfcDirection() : Object("IfcDirection") {} - ListOf< REAL, 2, 3 >::Out DirectionRatios; - }; + // C++ wrapper for IfcCondition + struct IfcCondition : IfcGroup, ObjectHelper<IfcCondition,0> { IfcCondition() : Object("IfcCondition") {} - // C++ wrapper for IfcBlock - struct IfcBlock : IfcCsgPrimitive3D, ObjectHelper<IfcBlock,3> { IfcBlock() : Object("IfcBlock") {} - IfcPositiveLengthMeasure::Out XLength; - IfcPositiveLengthMeasure::Out YLength; - IfcPositiveLengthMeasure::Out ZLength; }; - // C++ wrapper for IfcProjectOrderRecord - struct IfcProjectOrderRecord : IfcControl, ObjectHelper<IfcProjectOrderRecord,2> { IfcProjectOrderRecord() : Object("IfcProjectOrderRecord") {} - ListOf< Lazy< NotImplemented >, 1, 0 > Records; - IfcProjectOrderRecordTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcPort + struct IfcPort : IfcProduct, ObjectHelper<IfcPort,0> { IfcPort() : Object("IfcPort") {} - // C++ wrapper for IfcFlowMeterType - struct IfcFlowMeterType : IfcFlowControllerType, ObjectHelper<IfcFlowMeterType,1> { IfcFlowMeterType() : Object("IfcFlowMeterType") {} - IfcFlowMeterTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcControllerType - struct IfcControllerType : IfcDistributionControlElementType, ObjectHelper<IfcControllerType,1> { IfcControllerType() : Object("IfcControllerType") {} - IfcControllerTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSpace + struct IfcSpace : IfcSpatialStructureElement, ObjectHelper<IfcSpace,2> { IfcSpace() : Object("IfcSpace") {} + IfcInternalOrExternalEnum::Out InteriorOrExteriorSpace; + Maybe< IfcLengthMeasure::Out > ElevationWithFlooring; }; - // C++ wrapper for IfcBeam - struct IfcBeam : IfcBuildingElement, ObjectHelper<IfcBeam,0> { IfcBeam() : Object("IfcBeam") {} - + // C++ wrapper for IfcHeatExchangerType + struct IfcHeatExchangerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcHeatExchangerType,1> { IfcHeatExchangerType() : Object("IfcHeatExchangerType") {} + IfcHeatExchangerTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcArbitraryOpenProfileDef - struct IfcArbitraryOpenProfileDef : IfcProfileDef, ObjectHelper<IfcArbitraryOpenProfileDef,1> { IfcArbitraryOpenProfileDef() : Object("IfcArbitraryOpenProfileDef") {} - Lazy< IfcBoundedCurve > Curve; + // C++ wrapper for IfcTankType + struct IfcTankType : IfcFlowStorageDeviceType, ObjectHelper<IfcTankType,1> { IfcTankType() : Object("IfcTankType") {} + IfcTankTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcCenterLineProfileDef - struct IfcCenterLineProfileDef : IfcArbitraryOpenProfileDef, ObjectHelper<IfcCenterLineProfileDef,1> { IfcCenterLineProfileDef() : Object("IfcCenterLineProfileDef") {} - IfcPositiveLengthMeasure::Out Thickness; + // C++ wrapper for IfcInventory + struct IfcInventory : IfcGroup, ObjectHelper<IfcInventory,6> { IfcInventory() : Object("IfcInventory") {} + IfcInventoryTypeEnum::Out InventoryType; + IfcActorSelect::Out Jurisdiction; + ListOf< Lazy< NotImplemented >, 1, 0 > ResponsiblePersons; + Lazy< NotImplemented > LastUpdateDate; + Maybe< Lazy< NotImplemented > > CurrentValue; + Maybe< Lazy< NotImplemented > > OriginalValue; }; - // C++ wrapper for IfcTimeSeriesSchedule - struct IfcTimeSeriesSchedule : IfcControl, ObjectHelper<IfcTimeSeriesSchedule,3> { IfcTimeSeriesSchedule() : Object("IfcTimeSeriesSchedule") {} - Maybe< ListOf< IfcDateTimeSelect, 1, 0 >::Out > ApplicableDates; - IfcTimeSeriesScheduleTypeEnum::Out TimeSeriesScheduleType; - Lazy< NotImplemented > TimeSeries; + // C++ wrapper for IfcTransportElementType + struct IfcTransportElementType : IfcElementType, ObjectHelper<IfcTransportElementType,1> { IfcTransportElementType() : Object("IfcTransportElementType") {} + IfcTransportElementTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcRoundedEdgeFeature - struct IfcRoundedEdgeFeature : IfcEdgeFeature, ObjectHelper<IfcRoundedEdgeFeature,1> { IfcRoundedEdgeFeature() : Object("IfcRoundedEdgeFeature") {} - Maybe< IfcPositiveLengthMeasure::Out > Radius; + // C++ wrapper for IfcAirToAirHeatRecoveryType + struct IfcAirToAirHeatRecoveryType : IfcEnergyConversionDeviceType, ObjectHelper<IfcAirToAirHeatRecoveryType,1> { IfcAirToAirHeatRecoveryType() : Object("IfcAirToAirHeatRecoveryType") {} + IfcAirToAirHeatRecoveryTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcIShapeProfileDef - struct IfcIShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcIShapeProfileDef,5> { IfcIShapeProfileDef() : Object("IfcIShapeProfileDef") {} - IfcPositiveLengthMeasure::Out OverallWidth; - IfcPositiveLengthMeasure::Out OverallDepth; - IfcPositiveLengthMeasure::Out WebThickness; - IfcPositiveLengthMeasure::Out FlangeThickness; - Maybe< IfcPositiveLengthMeasure::Out > FilletRadius; + // C++ wrapper for IfcStairFlight + struct IfcStairFlight : IfcBuildingElement, ObjectHelper<IfcStairFlight,4> { IfcStairFlight() : Object("IfcStairFlight") {} + Maybe< INTEGER::Out > NumberOfRiser; + Maybe< INTEGER::Out > NumberOfTreads; + Maybe< IfcPositiveLengthMeasure::Out > RiserHeight; + Maybe< IfcPositiveLengthMeasure::Out > TreadLength; }; - // C++ wrapper for IfcSpaceHeaterType - struct IfcSpaceHeaterType : IfcEnergyConversionDeviceType, ObjectHelper<IfcSpaceHeaterType,1> { IfcSpaceHeaterType() : Object("IfcSpaceHeaterType") {} - IfcSpaceHeaterTypeEnum::Out PredefinedType; - }; + // C++ wrapper for IfcElectricalElement + struct IfcElectricalElement : IfcElement, ObjectHelper<IfcElectricalElement,0> { IfcElectricalElement() : Object("IfcElectricalElement") {} - // C++ wrapper for IfcFlowStorageDevice - struct IfcFlowStorageDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowStorageDevice,0> { IfcFlowStorageDevice() : Object("IfcFlowStorageDevice") {} + }; + // C++ wrapper for IfcSurfaceStyleWithTextures + struct IfcSurfaceStyleWithTextures : ObjectHelper<IfcSurfaceStyleWithTextures,1> { IfcSurfaceStyleWithTextures() : Object("IfcSurfaceStyleWithTextures") {} + ListOf< Lazy< NotImplemented >, 1, 0 > Textures; }; - // C++ wrapper for IfcRevolvedAreaSolid - struct IfcRevolvedAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcRevolvedAreaSolid,2> { IfcRevolvedAreaSolid() : Object("IfcRevolvedAreaSolid") {} - Lazy< IfcAxis1Placement > Axis; - IfcPlaneAngleMeasure::Out Angle; + // C++ wrapper for IfcBoundingBox + struct IfcBoundingBox : IfcGeometricRepresentationItem, ObjectHelper<IfcBoundingBox,4> { IfcBoundingBox() : Object("IfcBoundingBox") {} + Lazy< IfcCartesianPoint > Corner; + IfcPositiveLengthMeasure::Out XDim; + IfcPositiveLengthMeasure::Out YDim; + IfcPositiveLengthMeasure::Out ZDim; }; - // C++ wrapper for IfcDoor - struct IfcDoor : IfcBuildingElement, ObjectHelper<IfcDoor,2> { IfcDoor() : Object("IfcDoor") {} - Maybe< IfcPositiveLengthMeasure::Out > OverallHeight; - Maybe< IfcPositiveLengthMeasure::Out > OverallWidth; + // C++ wrapper for IfcWallType + struct IfcWallType : IfcBuildingElementType, ObjectHelper<IfcWallType,1> { IfcWallType() : Object("IfcWallType") {} + IfcWallTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcEllipse - struct IfcEllipse : IfcConic, ObjectHelper<IfcEllipse,2> { IfcEllipse() : Object("IfcEllipse") {} - IfcPositiveLengthMeasure::Out SemiAxis1; - IfcPositiveLengthMeasure::Out SemiAxis2; + // C++ wrapper for IfcMove + struct IfcMove : IfcTask, ObjectHelper<IfcMove,3> { IfcMove() : Object("IfcMove") {} + Lazy< IfcSpatialStructureElement > MoveFrom; + Lazy< IfcSpatialStructureElement > MoveTo; + Maybe< ListOf< IfcText, 1, 0 >::Out > PunchList; }; - // C++ wrapper for IfcTubeBundleType - struct IfcTubeBundleType : IfcEnergyConversionDeviceType, ObjectHelper<IfcTubeBundleType,1> { IfcTubeBundleType() : Object("IfcTubeBundleType") {} - IfcTubeBundleTypeEnum::Out PredefinedType; + // C++ wrapper for IfcCircle + struct IfcCircle : IfcConic, ObjectHelper<IfcCircle,1> { IfcCircle() : Object("IfcCircle") {} + IfcPositiveLengthMeasure::Out Radius; }; - // C++ wrapper for IfcAngularDimension - struct IfcAngularDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcAngularDimension,0> { IfcAngularDimension() : Object("IfcAngularDimension") {} + // C++ wrapper for IfcOffsetCurve2D + struct IfcOffsetCurve2D : IfcCurve, ObjectHelper<IfcOffsetCurve2D,3> { IfcOffsetCurve2D() : Object("IfcOffsetCurve2D") {} + Lazy< IfcCurve > BasisCurve; + IfcLengthMeasure::Out Distance; + LOGICAL::Out SelfIntersect; + }; + // C++ wrapper for IfcPointOnCurve + struct IfcPointOnCurve : IfcPoint, ObjectHelper<IfcPointOnCurve,2> { IfcPointOnCurve() : Object("IfcPointOnCurve") {} + Lazy< IfcCurve > BasisCurve; + IfcParameterValue::Out PointParameter; }; - // C++ wrapper for IfcFaceBasedSurfaceModel - struct IfcFaceBasedSurfaceModel : IfcGeometricRepresentationItem, ObjectHelper<IfcFaceBasedSurfaceModel,1> { IfcFaceBasedSurfaceModel() : Object("IfcFaceBasedSurfaceModel") {} - ListOf< Lazy< IfcConnectedFaceSet >, 1, 0 > FbsmFaces; + // C++ wrapper for IfcStructuralResultGroup + struct IfcStructuralResultGroup : IfcGroup, ObjectHelper<IfcStructuralResultGroup,3> { IfcStructuralResultGroup() : Object("IfcStructuralResultGroup") {} + IfcAnalysisTheoryTypeEnum::Out TheoryType; + Maybe< Lazy< IfcStructuralLoadGroup > > ResultForLoadGroup; + BOOLEAN::Out IsLinear; }; - // C++ wrapper for IfcCraneRailFShapeProfileDef - struct IfcCraneRailFShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCraneRailFShapeProfileDef,9> { IfcCraneRailFShapeProfileDef() : Object("IfcCraneRailFShapeProfileDef") {} - IfcPositiveLengthMeasure::Out OverallHeight; - IfcPositiveLengthMeasure::Out HeadWidth; - Maybe< IfcPositiveLengthMeasure::Out > Radius; - IfcPositiveLengthMeasure::Out HeadDepth2; - IfcPositiveLengthMeasure::Out HeadDepth3; - IfcPositiveLengthMeasure::Out WebThickness; - IfcPositiveLengthMeasure::Out BaseDepth1; - IfcPositiveLengthMeasure::Out BaseDepth2; - Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; + // C++ wrapper for IfcSectionedSpine + struct IfcSectionedSpine : IfcGeometricRepresentationItem, ObjectHelper<IfcSectionedSpine,3> { IfcSectionedSpine() : Object("IfcSectionedSpine") {} + Lazy< IfcCompositeCurve > SpineCurve; + ListOf< Lazy< IfcProfileDef >, 2, 0 > CrossSections; + ListOf< Lazy< IfcAxis2Placement3D >, 2, 0 > CrossSectionPositions; }; - // C++ wrapper for IfcColumnType - struct IfcColumnType : IfcBuildingElementType, ObjectHelper<IfcColumnType,1> { IfcColumnType() : Object("IfcColumnType") {} - IfcColumnTypeEnum::Out PredefinedType; + // C++ wrapper for IfcSlab + struct IfcSlab : IfcBuildingElement, ObjectHelper<IfcSlab,1> { IfcSlab() : Object("IfcSlab") {} + Maybe< IfcSlabTypeEnum::Out > PredefinedType; }; - // C++ wrapper for IfcTShapeProfileDef - struct IfcTShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcTShapeProfileDef,10> { IfcTShapeProfileDef() : Object("IfcTShapeProfileDef") {} - IfcPositiveLengthMeasure::Out Depth; - IfcPositiveLengthMeasure::Out FlangeWidth; - IfcPositiveLengthMeasure::Out WebThickness; - IfcPositiveLengthMeasure::Out FlangeThickness; - Maybe< IfcPositiveLengthMeasure::Out > FilletRadius; - Maybe< IfcPositiveLengthMeasure::Out > FlangeEdgeRadius; - Maybe< IfcPositiveLengthMeasure::Out > WebEdgeRadius; - Maybe< IfcPlaneAngleMeasure::Out > WebSlope; - Maybe< IfcPlaneAngleMeasure::Out > FlangeSlope; - Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; + // C++ wrapper for IfcVertex + struct IfcVertex : IfcTopologicalRepresentationItem, ObjectHelper<IfcVertex,0> { IfcVertex() : Object("IfcVertex") {} + }; - // C++ wrapper for IfcEnergyConversionDevice - struct IfcEnergyConversionDevice : IfcDistributionFlowElement, ObjectHelper<IfcEnergyConversionDevice,0> { IfcEnergyConversionDevice() : Object("IfcEnergyConversionDevice") {} + // C++ wrapper for IfcVertexPoint + struct IfcVertexPoint : IfcVertex, ObjectHelper<IfcVertexPoint,1> { IfcVertexPoint() : Object("IfcVertexPoint") {} + Lazy< IfcPoint > VertexGeometry; + }; + // C++ wrapper for IfcStructuralLinearAction + struct IfcStructuralLinearAction : IfcStructuralAction, ObjectHelper<IfcStructuralLinearAction,1> { IfcStructuralLinearAction() : Object("IfcStructuralLinearAction") {} + IfcProjectedOrTrueLengthEnum::Out ProjectedOrTrue; }; - // C++ wrapper for IfcWorkSchedule - struct IfcWorkSchedule : IfcWorkControl, ObjectHelper<IfcWorkSchedule,0> { IfcWorkSchedule() : Object("IfcWorkSchedule") {} + // C++ wrapper for IfcStructuralLinearActionVarying + struct IfcStructuralLinearActionVarying : IfcStructuralLinearAction, ObjectHelper<IfcStructuralLinearActionVarying,2> { IfcStructuralLinearActionVarying() : Object("IfcStructuralLinearActionVarying") {} + Lazy< NotImplemented > VaryingAppliedLoadLocation; + ListOf< Lazy< NotImplemented >, 1, 0 > SubsequentAppliedLoads; + }; + // C++ wrapper for IfcBuildingElementProxyType + struct IfcBuildingElementProxyType : IfcBuildingElementType, ObjectHelper<IfcBuildingElementProxyType,1> { IfcBuildingElementProxyType() : Object("IfcBuildingElementProxyType") {} + IfcBuildingElementProxyTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcZone - struct IfcZone : IfcGroup, ObjectHelper<IfcZone,0> { IfcZone() : Object("IfcZone") {} + // C++ wrapper for IfcProjectionElement + struct IfcProjectionElement : IfcFeatureElementAddition, ObjectHelper<IfcProjectionElement,0> { IfcProjectionElement() : Object("IfcProjectionElement") {} }; - // C++ wrapper for IfcTransportElement - struct IfcTransportElement : IfcElement, ObjectHelper<IfcTransportElement,3> { IfcTransportElement() : Object("IfcTransportElement") {} - Maybe< IfcTransportElementTypeEnum::Out > OperationType; - Maybe< IfcMassMeasure::Out > CapacityByWeight; - Maybe< IfcCountMeasure::Out > CapacityByNumber; + // C++ wrapper for IfcConversionBasedUnit + struct IfcConversionBasedUnit : IfcNamedUnit, ObjectHelper<IfcConversionBasedUnit,2> { IfcConversionBasedUnit() : Object("IfcConversionBasedUnit") {} + IfcLabel::Out Name; + Lazy< IfcMeasureWithUnit > ConversionFactor; }; // C++ wrapper for IfcGeometricRepresentationSubContext @@ -3680,36 +3737,40 @@ namespace IFC { Maybe< IfcLabel::Out > UserDefinedTargetView; }; - // C++ wrapper for IfcLShapeProfileDef - struct IfcLShapeProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcLShapeProfileDef,8> { IfcLShapeProfileDef() : Object("IfcLShapeProfileDef") {} - IfcPositiveLengthMeasure::Out Depth; - Maybe< IfcPositiveLengthMeasure::Out > Width; - IfcPositiveLengthMeasure::Out Thickness; - Maybe< IfcPositiveLengthMeasure::Out > FilletRadius; - Maybe< IfcPositiveLengthMeasure::Out > EdgeRadius; - Maybe< IfcPlaneAngleMeasure::Out > LegSlope; - Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInX; - Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; + // C++ wrapper for IfcAnnotationSurfaceOccurrence + struct IfcAnnotationSurfaceOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationSurfaceOccurrence,0> { IfcAnnotationSurfaceOccurrence() : Object("IfcAnnotationSurfaceOccurrence") {} + }; - // C++ wrapper for IfcGeometricCurveSet - struct IfcGeometricCurveSet : IfcGeometricSet, ObjectHelper<IfcGeometricCurveSet,0> { IfcGeometricCurveSet() : Object("IfcGeometricCurveSet") {} + // C++ wrapper for IfcRoundedEdgeFeature + struct IfcRoundedEdgeFeature : IfcEdgeFeature, ObjectHelper<IfcRoundedEdgeFeature,1> { IfcRoundedEdgeFeature() : Object("IfcRoundedEdgeFeature") {} + Maybe< IfcPositiveLengthMeasure::Out > Radius; + }; + // C++ wrapper for IfcElectricDistributionPoint + struct IfcElectricDistributionPoint : IfcFlowController, ObjectHelper<IfcElectricDistributionPoint,2> { IfcElectricDistributionPoint() : Object("IfcElectricDistributionPoint") {} + IfcElectricDistributionPointFunctionEnum::Out DistributionPointFunction; + Maybe< IfcLabel::Out > UserDefinedFunction; }; - // C++ wrapper for IfcActor - struct IfcActor : IfcObject, ObjectHelper<IfcActor,1> { IfcActor() : Object("IfcActor") {} - IfcActorSelect::Out TheActor; + // C++ wrapper for IfcCableCarrierSegmentType + struct IfcCableCarrierSegmentType : IfcFlowSegmentType, ObjectHelper<IfcCableCarrierSegmentType,1> { IfcCableCarrierSegmentType() : Object("IfcCableCarrierSegmentType") {} + IfcCableCarrierSegmentTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcOccupant - struct IfcOccupant : IfcActor, ObjectHelper<IfcOccupant,1> { IfcOccupant() : Object("IfcOccupant") {} - IfcOccupantTypeEnum::Out PredefinedType; + // C++ wrapper for IfcWallStandardCase + struct IfcWallStandardCase : IfcWall, ObjectHelper<IfcWallStandardCase,0> { IfcWallStandardCase() : Object("IfcWallStandardCase") {} + }; - // C++ wrapper for IfcBooleanClippingResult - struct IfcBooleanClippingResult : IfcBooleanResult, ObjectHelper<IfcBooleanClippingResult,0> { IfcBooleanClippingResult() : Object("IfcBooleanClippingResult") {} + // C++ wrapper for IfcCsgSolid + struct IfcCsgSolid : IfcSolidModel, ObjectHelper<IfcCsgSolid,1> { IfcCsgSolid() : Object("IfcCsgSolid") {} + IfcCsgSelect::Out TreeRootExpression; + }; + // C++ wrapper for IfcBeamType + struct IfcBeamType : IfcBuildingElementType, ObjectHelper<IfcBeamType,1> { IfcBeamType() : Object("IfcBeamType") {} + IfcBeamTypeEnum::Out PredefinedType; }; // C++ wrapper for IfcAnnotationFillArea @@ -3718,104 +3779,136 @@ namespace IFC { Maybe< ListOf< Lazy< IfcCurve >, 1, 0 > > InnerBoundaries; }; - // C++ wrapper for IfcLightSourceSpot - struct IfcLightSourceSpot : IfcLightSourcePositional, ObjectHelper<IfcLightSourceSpot,4> { IfcLightSourceSpot() : Object("IfcLightSourceSpot") {} - Lazy< IfcDirection > Orientation; - Maybe< IfcReal::Out > ConcentrationExponent; - IfcPositivePlaneAngleMeasure::Out SpreadAngle; - IfcPositivePlaneAngleMeasure::Out BeamWidthAngle; + // C++ wrapper for IfcStructuralCurveMemberVarying + struct IfcStructuralCurveMemberVarying : IfcStructuralCurveMember, ObjectHelper<IfcStructuralCurveMemberVarying,0> { IfcStructuralCurveMemberVarying() : Object("IfcStructuralCurveMemberVarying") {} + }; - // C++ wrapper for IfcFireSuppressionTerminalType - struct IfcFireSuppressionTerminalType : IfcFlowTerminalType, ObjectHelper<IfcFireSuppressionTerminalType,1> { IfcFireSuppressionTerminalType() : Object("IfcFireSuppressionTerminalType") {} - IfcFireSuppressionTerminalTypeEnum::Out PredefinedType; + // C++ wrapper for IfcPointOnSurface + struct IfcPointOnSurface : IfcPoint, ObjectHelper<IfcPointOnSurface,3> { IfcPointOnSurface() : Object("IfcPointOnSurface") {} + Lazy< IfcSurface > BasisSurface; + IfcParameterValue::Out PointParameterU; + IfcParameterValue::Out PointParameterV; }; - // C++ wrapper for IfcElectricGeneratorType - struct IfcElectricGeneratorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcElectricGeneratorType,1> { IfcElectricGeneratorType() : Object("IfcElectricGeneratorType") {} - IfcElectricGeneratorTypeEnum::Out PredefinedType; + // C++ wrapper for IfcOrderAction + struct IfcOrderAction : IfcTask, ObjectHelper<IfcOrderAction,1> { IfcOrderAction() : Object("IfcOrderAction") {} + IfcIdentifier::Out ActionID; }; - // C++ wrapper for IfcInventory - struct IfcInventory : IfcGroup, ObjectHelper<IfcInventory,6> { IfcInventory() : Object("IfcInventory") {} - IfcInventoryTypeEnum::Out InventoryType; - IfcActorSelect::Out Jurisdiction; - ListOf< Lazy< NotImplemented >, 1, 0 > ResponsiblePersons; - Lazy< NotImplemented > LastUpdateDate; - Maybe< Lazy< NotImplemented > > CurrentValue; - Maybe< Lazy< NotImplemented > > OriginalValue; + // C++ wrapper for IfcEdgeLoop + struct IfcEdgeLoop : IfcLoop, ObjectHelper<IfcEdgeLoop,1> { IfcEdgeLoop() : Object("IfcEdgeLoop") {} + ListOf< Lazy< IfcOrientedEdge >, 1, 0 > EdgeList; }; - // C++ wrapper for IfcPolyline - struct IfcPolyline : IfcBoundedCurve, ObjectHelper<IfcPolyline,1> { IfcPolyline() : Object("IfcPolyline") {} - ListOf< Lazy< IfcCartesianPoint >, 2, 0 > Points; + // C++ wrapper for IfcAnnotationFillAreaOccurrence + struct IfcAnnotationFillAreaOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationFillAreaOccurrence,2> { IfcAnnotationFillAreaOccurrence() : Object("IfcAnnotationFillAreaOccurrence") {} + Maybe< Lazy< IfcPoint > > FillStyleTarget; + Maybe< IfcGlobalOrLocalEnum::Out > GlobalOrLocal; }; - // C++ wrapper for IfcBoxedHalfSpace - struct IfcBoxedHalfSpace : IfcHalfSpaceSolid, ObjectHelper<IfcBoxedHalfSpace,1> { IfcBoxedHalfSpace() : Object("IfcBoxedHalfSpace") {} - Lazy< IfcBoundingBox > Enclosure; + // C++ wrapper for IfcWorkPlan + struct IfcWorkPlan : IfcWorkControl, ObjectHelper<IfcWorkPlan,0> { IfcWorkPlan() : Object("IfcWorkPlan") {} + }; - // C++ wrapper for IfcAirTerminalType - struct IfcAirTerminalType : IfcFlowTerminalType, ObjectHelper<IfcAirTerminalType,1> { IfcAirTerminalType() : Object("IfcAirTerminalType") {} - IfcAirTerminalTypeEnum::Out PredefinedType; + // C++ wrapper for IfcEllipse + struct IfcEllipse : IfcConic, ObjectHelper<IfcEllipse,2> { IfcEllipse() : Object("IfcEllipse") {} + IfcPositiveLengthMeasure::Out SemiAxis1; + IfcPositiveLengthMeasure::Out SemiAxis2; }; - // C++ wrapper for IfcDistributionPort - struct IfcDistributionPort : IfcPort, ObjectHelper<IfcDistributionPort,1> { IfcDistributionPort() : Object("IfcDistributionPort") {} - Maybe< IfcFlowDirectionEnum::Out > FlowDirection; + // C++ wrapper for IfcProductDefinitionShape + struct IfcProductDefinitionShape : IfcProductRepresentation, ObjectHelper<IfcProductDefinitionShape,0> { IfcProductDefinitionShape() : Object("IfcProductDefinitionShape") {} + }; - // C++ wrapper for IfcCostItem - struct IfcCostItem : IfcControl, ObjectHelper<IfcCostItem,0> { IfcCostItem() : Object("IfcCostItem") {} + // C++ wrapper for IfcProjectionCurve + struct IfcProjectionCurve : IfcAnnotationCurveOccurrence, ObjectHelper<IfcProjectionCurve,0> { IfcProjectionCurve() : Object("IfcProjectionCurve") {} }; - // C++ wrapper for IfcStructuredDimensionCallout - struct IfcStructuredDimensionCallout : IfcDraughtingCallout, ObjectHelper<IfcStructuredDimensionCallout,0> { IfcStructuredDimensionCallout() : Object("IfcStructuredDimensionCallout") {} + // C++ wrapper for IfcElectricalCircuit + struct IfcElectricalCircuit : IfcSystem, ObjectHelper<IfcElectricalCircuit,0> { IfcElectricalCircuit() : Object("IfcElectricalCircuit") {} }; - // C++ wrapper for IfcStructuralResultGroup - struct IfcStructuralResultGroup : IfcGroup, ObjectHelper<IfcStructuralResultGroup,3> { IfcStructuralResultGroup() : Object("IfcStructuralResultGroup") {} - IfcAnalysisTheoryTypeEnum::Out TheoryType; - Maybe< Lazy< IfcStructuralLoadGroup > > ResultForLoadGroup; - BOOLEAN::Out IsLinear; + // C++ wrapper for IfcRationalBezierCurve + struct IfcRationalBezierCurve : IfcBezierCurve, ObjectHelper<IfcRationalBezierCurve,1> { IfcRationalBezierCurve() : Object("IfcRationalBezierCurve") {} + ListOf< REAL, 2, 0 >::Out WeightsData; }; - // C++ wrapper for IfcOrientedEdge - struct IfcOrientedEdge : IfcEdge, ObjectHelper<IfcOrientedEdge,2> { IfcOrientedEdge() : Object("IfcOrientedEdge") {} - Lazy< IfcEdge > EdgeElement; - BOOLEAN::Out Orientation; + // C++ wrapper for IfcStructuralPointAction + struct IfcStructuralPointAction : IfcStructuralAction, ObjectHelper<IfcStructuralPointAction,0> { IfcStructuralPointAction() : Object("IfcStructuralPointAction") {} + }; - // C++ wrapper for IfcCsgSolid - struct IfcCsgSolid : IfcSolidModel, ObjectHelper<IfcCsgSolid,1> { IfcCsgSolid() : Object("IfcCsgSolid") {} - IfcCsgSelect::Out TreeRootExpression; + // C++ wrapper for IfcPipeSegmentType + struct IfcPipeSegmentType : IfcFlowSegmentType, ObjectHelper<IfcPipeSegmentType,1> { IfcPipeSegmentType() : Object("IfcPipeSegmentType") {} + IfcPipeSegmentTypeEnum::Out PredefinedType; }; - // C++ wrapper for IfcPlanarBox - struct IfcPlanarBox : IfcPlanarExtent, ObjectHelper<IfcPlanarBox,1> { IfcPlanarBox() : Object("IfcPlanarBox") {} - IfcAxis2Placement::Out Placement; + // C++ wrapper for IfcTwoDirectionRepeatFactor + struct IfcTwoDirectionRepeatFactor : IfcOneDirectionRepeatFactor, ObjectHelper<IfcTwoDirectionRepeatFactor,1> { IfcTwoDirectionRepeatFactor() : Object("IfcTwoDirectionRepeatFactor") {} + Lazy< IfcVector > SecondRepeatFactor; }; - // C++ wrapper for IfcMaterialDefinitionRepresentation - struct IfcMaterialDefinitionRepresentation : IfcProductRepresentation, ObjectHelper<IfcMaterialDefinitionRepresentation,1> { IfcMaterialDefinitionRepresentation() : Object("IfcMaterialDefinitionRepresentation") {} - Lazy< NotImplemented > RepresentedMaterial; + // C++ wrapper for IfcShapeRepresentation + struct IfcShapeRepresentation : IfcShapeModel, ObjectHelper<IfcShapeRepresentation,0> { IfcShapeRepresentation() : Object("IfcShapeRepresentation") {} + }; - // C++ wrapper for IfcAsymmetricIShapeProfileDef - struct IfcAsymmetricIShapeProfileDef : IfcIShapeProfileDef, ObjectHelper<IfcAsymmetricIShapeProfileDef,4> { IfcAsymmetricIShapeProfileDef() : Object("IfcAsymmetricIShapeProfileDef") {} - IfcPositiveLengthMeasure::Out TopFlangeWidth; - Maybe< IfcPositiveLengthMeasure::Out > TopFlangeThickness; - Maybe< IfcPositiveLengthMeasure::Out > TopFlangeFilletRadius; - Maybe< IfcPositiveLengthMeasure::Out > CentreOfGravityInY; + // C++ wrapper for IfcPropertySet + struct IfcPropertySet : IfcPropertySetDefinition, ObjectHelper<IfcPropertySet,1> { IfcPropertySet() : Object("IfcPropertySet") {} + ListOf< Lazy< IfcProperty >, 1, 0 > HasProperties; }; - // C++ wrapper for IfcRepresentationMap - struct IfcRepresentationMap : ObjectHelper<IfcRepresentationMap,2> { IfcRepresentationMap() : Object("IfcRepresentationMap") {} - IfcAxis2Placement::Out MappingOrigin; - Lazy< IfcRepresentation > MappedRepresentation; + // C++ wrapper for IfcSurfaceStyleRendering + struct IfcSurfaceStyleRendering : IfcSurfaceStyleShading, ObjectHelper<IfcSurfaceStyleRendering,8> { IfcSurfaceStyleRendering() : Object("IfcSurfaceStyleRendering") {} + Maybe< IfcNormalisedRatioMeasure::Out > Transparency; + Maybe< IfcColourOrFactor::Out > DiffuseColour; + Maybe< IfcColourOrFactor::Out > TransmissionColour; + Maybe< IfcColourOrFactor::Out > DiffuseTransmissionColour; + Maybe< IfcColourOrFactor::Out > ReflectionColour; + Maybe< IfcColourOrFactor::Out > SpecularColour; + Maybe< IfcSpecularHighlightSelect::Out > SpecularHighlight; + IfcReflectanceMethodEnum::Out ReflectanceMethod; + }; + + // C++ wrapper for IfcDistributionPort + struct IfcDistributionPort : IfcPort, ObjectHelper<IfcDistributionPort,1> { IfcDistributionPort() : Object("IfcDistributionPort") {} + Maybe< IfcFlowDirectionEnum::Out > FlowDirection; + }; + + // C++ wrapper for IfcPipeFittingType + struct IfcPipeFittingType : IfcFlowFittingType, ObjectHelper<IfcPipeFittingType,1> { IfcPipeFittingType() : Object("IfcPipeFittingType") {} + IfcPipeFittingTypeEnum::Out PredefinedType; + }; + + // C++ wrapper for IfcTransportElement + struct IfcTransportElement : IfcElement, ObjectHelper<IfcTransportElement,3> { IfcTransportElement() : Object("IfcTransportElement") {} + Maybe< IfcTransportElementTypeEnum::Out > OperationType; + Maybe< IfcMassMeasure::Out > CapacityByWeight; + Maybe< IfcCountMeasure::Out > CapacityByNumber; + }; + + // C++ wrapper for IfcAnnotationTextOccurrence + struct IfcAnnotationTextOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationTextOccurrence,0> { IfcAnnotationTextOccurrence() : Object("IfcAnnotationTextOccurrence") {} + + }; + + // C++ wrapper for IfcStructuralAnalysisModel + struct IfcStructuralAnalysisModel : IfcSystem, ObjectHelper<IfcStructuralAnalysisModel,4> { IfcStructuralAnalysisModel() : Object("IfcStructuralAnalysisModel") {} + IfcAnalysisModelTypeEnum::Out PredefinedType; + Maybe< Lazy< IfcAxis2Placement3D > > OrientationOf2DPlane; + Maybe< ListOf< Lazy< IfcStructuralLoadGroup >, 1, 0 > > LoadedBy; + Maybe< ListOf< Lazy< IfcStructuralResultGroup >, 1, 0 > > HasResults; + }; + + // C++ wrapper for IfcConditionCriterion + struct IfcConditionCriterion : IfcControl, ObjectHelper<IfcConditionCriterion,2> { IfcConditionCriterion() : Object("IfcConditionCriterion") {} + IfcConditionCriterionSelect::Out Criterion; + IfcDateTimeSelect::Out CriterionDateTime; }; void GetSchema(EXPRESS::ConversionSchema& out); @@ -3834,421 +3927,437 @@ namespace STEP { DECL_CONV_STUB(IfcTypeObject); DECL_CONV_STUB(IfcTypeProduct); DECL_CONV_STUB(IfcElementType); - DECL_CONV_STUB(IfcFurnishingElementType); - DECL_CONV_STUB(IfcFurnitureType); - DECL_CONV_STUB(IfcObject); - DECL_CONV_STUB(IfcProduct); - DECL_CONV_STUB(IfcGrid); - DECL_CONV_STUB(IfcRepresentationItem); - DECL_CONV_STUB(IfcGeometricRepresentationItem); - DECL_CONV_STUB(IfcOneDirectionRepeatFactor); - DECL_CONV_STUB(IfcTwoDirectionRepeatFactor); - DECL_CONV_STUB(IfcElement); - DECL_CONV_STUB(IfcElementComponent); - DECL_CONV_STUB(IfcSpatialStructureElementType); - DECL_CONV_STUB(IfcControl); - DECL_CONV_STUB(IfcActionRequest); DECL_CONV_STUB(IfcDistributionElementType); DECL_CONV_STUB(IfcDistributionFlowElementType); - DECL_CONV_STUB(IfcEnergyConversionDeviceType); - DECL_CONV_STUB(IfcCooledBeamType); - DECL_CONV_STUB(IfcCsgPrimitive3D); - DECL_CONV_STUB(IfcRectangularPyramid); - DECL_CONV_STUB(IfcSurface); - DECL_CONV_STUB(IfcBoundedSurface); - DECL_CONV_STUB(IfcRectangularTrimmedSurface); - DECL_CONV_STUB(IfcGroup); + DECL_CONV_STUB(IfcFlowControllerType); + DECL_CONV_STUB(IfcElectricTimeControlType); + DECL_CONV_STUB(IfcRepresentation); + DECL_CONV_STUB(IfcShapeModel); + DECL_CONV_STUB(IfcTopologyRepresentation); DECL_CONV_STUB(IfcRelationship); - DECL_CONV_STUB(IfcHalfSpaceSolid); - DECL_CONV_STUB(IfcPolygonalBoundedHalfSpace); - DECL_CONV_STUB(IfcAirToAirHeatRecoveryType); + DECL_CONV_STUB(IfcRelConnects); DECL_CONV_STUB(IfcFlowFittingType); - DECL_CONV_STUB(IfcPipeFittingType); - DECL_CONV_STUB(IfcRepresentation); - DECL_CONV_STUB(IfcStyleModel); - DECL_CONV_STUB(IfcStyledRepresentation); - DECL_CONV_STUB(IfcBooleanResult); - DECL_CONV_STUB(IfcFeatureElement); - DECL_CONV_STUB(IfcFeatureElementSubtraction); - DECL_CONV_STUB(IfcOpeningElement); - DECL_CONV_STUB(IfcConditionCriterion); - DECL_CONV_STUB(IfcFlowTerminalType); - DECL_CONV_STUB(IfcFlowControllerType); - DECL_CONV_STUB(IfcSwitchingDeviceType); - DECL_CONV_STUB(IfcSystem); - DECL_CONV_STUB(IfcElectricalCircuit); - DECL_CONV_STUB(IfcUnitaryEquipmentType); - DECL_CONV_STUB(IfcPort); - DECL_CONV_STUB(IfcPlacement); - DECL_CONV_STUB(IfcProfileDef); - DECL_CONV_STUB(IfcArbitraryClosedProfileDef); + DECL_CONV_STUB(IfcCableCarrierFittingType); + DECL_CONV_STUB(IfcEnergyConversionDeviceType); + DECL_CONV_STUB(IfcCoilType); + DECL_CONV_STUB(IfcObject); + DECL_CONV_STUB(IfcControl); + DECL_CONV_STUB(IfcPerformanceHistory); + DECL_CONV_STUB(IfcRepresentationItem); + DECL_CONV_STUB(IfcGeometricRepresentationItem); + DECL_CONV_STUB(IfcTextLiteral); + DECL_CONV_STUB(IfcTextLiteralWithExtent); + DECL_CONV_STUB(IfcProductRepresentation); + DECL_CONV_STUB(IfcProduct); + DECL_CONV_STUB(IfcElement); + DECL_CONV_STUB(IfcDistributionElement); + DECL_CONV_STUB(IfcDistributionFlowElement); DECL_CONV_STUB(IfcCurve); - DECL_CONV_STUB(IfcConic); - DECL_CONV_STUB(IfcCircle); + DECL_CONV_STUB(IfcBoundedCurve); + DECL_CONV_STUB(IfcCompositeCurve); + DECL_CONV_STUB(Ifc2DCompositeCurve); + DECL_CONV_STUB(IfcCartesianTransformationOperator); + DECL_CONV_STUB(IfcCartesianTransformationOperator3D); + DECL_CONV_STUB(IfcProperty); + DECL_CONV_STUB(IfcSimpleProperty); + DECL_CONV_STUB(IfcPropertyEnumeratedValue); + DECL_CONV_STUB(IfcBuildingElementType); + DECL_CONV_STUB(IfcStairFlightType); + DECL_CONV_STUB(IfcSurface); DECL_CONV_STUB(IfcElementarySurface); DECL_CONV_STUB(IfcPlane); - DECL_CONV_STUB(IfcCostSchedule); - DECL_CONV_STUB(IfcRightCircularCone); - DECL_CONV_STUB(IfcElementAssembly); - DECL_CONV_STUB(IfcBuildingElement); - DECL_CONV_STUB(IfcMember); - DECL_CONV_STUB(IfcBuildingElementProxy); - DECL_CONV_STUB(IfcStructuralActivity); - DECL_CONV_STUB(IfcStructuralAction); - DECL_CONV_STUB(IfcStructuralPlanarAction); - DECL_CONV_STUB(IfcTopologicalRepresentationItem); - DECL_CONV_STUB(IfcConnectedFaceSet); - DECL_CONV_STUB(IfcSweptSurface); - DECL_CONV_STUB(IfcSurfaceOfLinearExtrusion); - DECL_CONV_STUB(IfcArbitraryProfileDefWithVoids); + DECL_CONV_STUB(IfcBooleanResult); + DECL_CONV_STUB(IfcBooleanClippingResult); + DECL_CONV_STUB(IfcSolidModel); + DECL_CONV_STUB(IfcManifoldSolidBrep); + DECL_CONV_STUB(IfcFlowTerminalType); + DECL_CONV_STUB(IfcStackTerminalType); + DECL_CONV_STUB(IfcStructuralItem); + DECL_CONV_STUB(IfcStructuralConnection); + DECL_CONV_STUB(IfcStructuralCurveConnection); + DECL_CONV_STUB(IfcJunctionBoxType); + DECL_CONV_STUB(IfcPropertyDefinition); + DECL_CONV_STUB(IfcPropertySetDefinition); DECL_CONV_STUB(IfcProcess); + DECL_CONV_STUB(IfcTask); + DECL_CONV_STUB(IfcRelFillsElement); DECL_CONV_STUB(IfcProcedure); - DECL_CONV_STUB(IfcVector); - DECL_CONV_STUB(IfcFaceBound); - DECL_CONV_STUB(IfcFaceOuterBound); - DECL_CONV_STUB(IfcFeatureElementAddition); - DECL_CONV_STUB(IfcNamedUnit); - DECL_CONV_STUB(IfcConversionBasedUnit); - DECL_CONV_STUB(IfcHeatExchangerType); - DECL_CONV_STUB(IfcPresentationStyleAssignment); - DECL_CONV_STUB(IfcFlowTreatmentDeviceType); - DECL_CONV_STUB(IfcFilterType); + DECL_CONV_STUB(IfcProxy); DECL_CONV_STUB(IfcResource); - DECL_CONV_STUB(IfcEvaporativeCoolerType); - DECL_CONV_STUB(IfcOffsetCurve2D); + DECL_CONV_STUB(IfcConstructionResource); + DECL_CONV_STUB(IfcSubContractResource); + DECL_CONV_STUB(IfcRelContainedInSpatialStructure); + DECL_CONV_STUB(IfcTopologicalRepresentationItem); DECL_CONV_STUB(IfcEdge); - DECL_CONV_STUB(IfcSubedge); - DECL_CONV_STUB(IfcProxy); - DECL_CONV_STUB(IfcLine); - DECL_CONV_STUB(IfcColumn); + DECL_CONV_STUB(IfcEdgeCurve); + DECL_CONV_STUB(IfcPlateType); DECL_CONV_STUB(IfcObjectPlacement); DECL_CONV_STUB(IfcGridPlacement); - DECL_CONV_STUB(IfcDistributionControlElementType); - DECL_CONV_STUB(IfcRelConnects); - DECL_CONV_STUB(IfcAnnotation); - DECL_CONV_STUB(IfcPlate); - DECL_CONV_STUB(IfcSolidModel); - DECL_CONV_STUB(IfcManifoldSolidBrep); - DECL_CONV_STUB(IfcFlowStorageDeviceType); - DECL_CONV_STUB(IfcStructuralItem); - DECL_CONV_STUB(IfcStructuralMember); - DECL_CONV_STUB(IfcStructuralCurveMember); - DECL_CONV_STUB(IfcStructuralConnection); - DECL_CONV_STUB(IfcStructuralSurfaceConnection); - DECL_CONV_STUB(IfcCoilType); - DECL_CONV_STUB(IfcDuctFittingType); - DECL_CONV_STUB(IfcStyledItem); - DECL_CONV_STUB(IfcAnnotationOccurrence); - DECL_CONV_STUB(IfcAnnotationCurveOccurrence); - DECL_CONV_STUB(IfcDimensionCurve); - DECL_CONV_STUB(IfcBoundedCurve); - DECL_CONV_STUB(IfcAxis1Placement); - DECL_CONV_STUB(IfcStructuralPointAction); - DECL_CONV_STUB(IfcSpatialStructureElement); - DECL_CONV_STUB(IfcSpace); - DECL_CONV_STUB(IfcContextDependentUnit); - DECL_CONV_STUB(IfcCoolingTowerType); - DECL_CONV_STUB(IfcFacetedBrepWithVoids); - DECL_CONV_STUB(IfcValveType); - DECL_CONV_STUB(IfcSystemFurnitureElementType); - DECL_CONV_STUB(IfcDiscreteAccessory); - DECL_CONV_STUB(IfcBuildingElementType); - DECL_CONV_STUB(IfcRailingType); - DECL_CONV_STUB(IfcGasTerminalType); - DECL_CONV_STUB(IfcSpaceProgram); - DECL_CONV_STUB(IfcCovering); + DECL_CONV_STUB(IfcFireSuppressionTerminalType); + DECL_CONV_STUB(IfcFlowStorageDevice); + DECL_CONV_STUB(IfcSweptSurface); + DECL_CONV_STUB(IfcSurfaceOfRevolution); + DECL_CONV_STUB(IfcOrientedEdge); + DECL_CONV_STUB(IfcDirection); + DECL_CONV_STUB(IfcProfileDef); + DECL_CONV_STUB(IfcParameterizedProfileDef); + DECL_CONV_STUB(IfcCShapeProfileDef); + DECL_CONV_STUB(IfcFeatureElement); + DECL_CONV_STUB(IfcFeatureElementSubtraction); + DECL_CONV_STUB(IfcEdgeFeature); + DECL_CONV_STUB(IfcChamferEdgeFeature); + DECL_CONV_STUB(IfcBuildingElement); + DECL_CONV_STUB(IfcColumn); + DECL_CONV_STUB(IfcPropertyReferenceValue); + DECL_CONV_STUB(IfcElectricMotorType); + DECL_CONV_STUB(IfcSpatialStructureElementType); + DECL_CONV_STUB(IfcSpaceType); + DECL_CONV_STUB(IfcColumnType); + DECL_CONV_STUB(IfcCraneRailAShapeProfileDef); + DECL_CONV_STUB(IfcCondenserType); + DECL_CONV_STUB(IfcCircleProfileDef); + DECL_CONV_STUB(IfcCircleHollowProfileDef); + DECL_CONV_STUB(IfcPlacement); + DECL_CONV_STUB(IfcAxis2Placement3D); DECL_CONV_STUB(IfcPresentationStyle); - DECL_CONV_STUB(IfcElectricHeaterType); - DECL_CONV_STUB(IfcBuildingStorey); - DECL_CONV_STUB(IfcVertex); - DECL_CONV_STUB(IfcVertexPoint); + DECL_CONV_STUB(IfcEquipmentElement); + DECL_CONV_STUB(IfcCompositeCurveSegment); + DECL_CONV_STUB(IfcRectangleProfileDef); + DECL_CONV_STUB(IfcBuildingElementProxy); + DECL_CONV_STUB(IfcDistributionControlElementType); DECL_CONV_STUB(IfcFlowInstrumentType); - DECL_CONV_STUB(IfcParameterizedProfileDef); - DECL_CONV_STUB(IfcUShapeProfileDef); - DECL_CONV_STUB(IfcRamp); - DECL_CONV_STUB(IfcCompositeCurve); - DECL_CONV_STUB(IfcStructuralCurveMemberVarying); - DECL_CONV_STUB(IfcRampFlightType); DECL_CONV_STUB(IfcDraughtingCallout); DECL_CONV_STUB(IfcDimensionCurveDirectedCallout); - DECL_CONV_STUB(IfcRadiusDimension); - DECL_CONV_STUB(IfcEdgeFeature); - DECL_CONV_STUB(IfcSweptAreaSolid); - DECL_CONV_STUB(IfcExtrudedAreaSolid); - DECL_CONV_STUB(IfcAnnotationTextOccurrence); - DECL_CONV_STUB(IfcStair); - DECL_CONV_STUB(IfcFillAreaStyleTileSymbolWithStyle); - DECL_CONV_STUB(IfcAnnotationSymbolOccurrence); - DECL_CONV_STUB(IfcTerminatorSymbol); - DECL_CONV_STUB(IfcDimensionCurveTerminator); - DECL_CONV_STUB(IfcRectangleProfileDef); - DECL_CONV_STUB(IfcRectangleHollowProfileDef); - DECL_CONV_STUB(IfcLocalPlacement); - DECL_CONV_STUB(IfcTask); - DECL_CONV_STUB(IfcAnnotationFillAreaOccurrence); - DECL_CONV_STUB(IfcFace); - DECL_CONV_STUB(IfcFlowSegmentType); - DECL_CONV_STUB(IfcDuctSegmentType); - DECL_CONV_STUB(IfcConstructionResource); - DECL_CONV_STUB(IfcConstructionEquipmentResource); - DECL_CONV_STUB(IfcSanitaryTerminalType); - DECL_CONV_STUB(IfcCircleProfileDef); - DECL_CONV_STUB(IfcStructuralReaction); - DECL_CONV_STUB(IfcStructuralPointReaction); - DECL_CONV_STUB(IfcRailing); - DECL_CONV_STUB(IfcTextLiteral); - DECL_CONV_STUB(IfcCartesianTransformationOperator); DECL_CONV_STUB(IfcLinearDimension); - DECL_CONV_STUB(IfcDamperType); - DECL_CONV_STUB(IfcSIUnit); - DECL_CONV_STUB(IfcMeasureWithUnit); - DECL_CONV_STUB(IfcDistributionElement); - DECL_CONV_STUB(IfcDistributionControlElement); - DECL_CONV_STUB(IfcTransformerType); - DECL_CONV_STUB(IfcLaborResource); - DECL_CONV_STUB(IfcDerivedProfileDef); - DECL_CONV_STUB(IfcFurnitureStandard); - DECL_CONV_STUB(IfcStairFlightType); - DECL_CONV_STUB(IfcWorkControl); - DECL_CONV_STUB(IfcWorkPlan); - DECL_CONV_STUB(IfcCondition); - DECL_CONV_STUB(IfcRelVoidsElement); - DECL_CONV_STUB(IfcWindow); - DECL_CONV_STUB(IfcProtectiveDeviceType); - DECL_CONV_STUB(IfcJunctionBoxType); - DECL_CONV_STUB(IfcStructuralAnalysisModel); - DECL_CONV_STUB(IfcAxis2Placement2D); - DECL_CONV_STUB(IfcSpaceType); - DECL_CONV_STUB(IfcEllipseProfileDef); - DECL_CONV_STUB(IfcDistributionFlowElement); - DECL_CONV_STUB(IfcFlowMovingDevice); - DECL_CONV_STUB(IfcSurfaceStyleWithTextures); - DECL_CONV_STUB(IfcGeometricSet); + DECL_CONV_STUB(IfcElementAssembly); + DECL_CONV_STUB(IfcCsgPrimitive3D); + DECL_CONV_STUB(IfcRightCircularCone); DECL_CONV_STUB(IfcProjectOrder); - DECL_CONV_STUB(IfcBSplineCurve); - DECL_CONV_STUB(IfcBezierCurve); - DECL_CONV_STUB(IfcStructuralPointConnection); - DECL_CONV_STUB(IfcFlowController); - DECL_CONV_STUB(IfcElectricDistributionPoint); - DECL_CONV_STUB(IfcSite); + DECL_CONV_STUB(IfcLShapeProfileDef); + DECL_CONV_STUB(IfcAngularDimension); + DECL_CONV_STUB(IfcLocalPlacement); + DECL_CONV_STUB(IfcSweptAreaSolid); + DECL_CONV_STUB(IfcRevolvedAreaSolid); + DECL_CONV_STUB(IfcStructuralSurfaceConnection); + DECL_CONV_STUB(IfcRadiusDimension); + DECL_CONV_STUB(IfcSweptDiskSolid); + DECL_CONV_STUB(IfcHalfSpaceSolid); + DECL_CONV_STUB(IfcPolygonalBoundedHalfSpace); + DECL_CONV_STUB(IfcTimeSeriesSchedule); + DECL_CONV_STUB(IfcCooledBeamType); + DECL_CONV_STUB(IfcProject); + DECL_CONV_STUB(IfcEvaporatorType); + DECL_CONV_STUB(IfcLaborResource); + DECL_CONV_STUB(IfcPropertyBoundedValue); + DECL_CONV_STUB(IfcRampFlightType); + DECL_CONV_STUB(IfcMember); + DECL_CONV_STUB(IfcTubeBundleType); + DECL_CONV_STUB(IfcValveType); + DECL_CONV_STUB(IfcTrimmedCurve); + DECL_CONV_STUB(IfcRelDefines); + DECL_CONV_STUB(IfcRelDefinesByProperties); + DECL_CONV_STUB(IfcActor); + DECL_CONV_STUB(IfcOccupant); + DECL_CONV_STUB(IfcHumidifierType); + DECL_CONV_STUB(IfcArbitraryOpenProfileDef); + DECL_CONV_STUB(IfcPermit); DECL_CONV_STUB(IfcOffsetCurve3D); + DECL_CONV_STUB(IfcLightSource); + DECL_CONV_STUB(IfcLightSourcePositional); + DECL_CONV_STUB(IfcCompositeProfileDef); + DECL_CONV_STUB(IfcRamp); + DECL_CONV_STUB(IfcFlowMovingDevice); + DECL_CONV_STUB(IfcSpaceHeaterType); + DECL_CONV_STUB(IfcLampType); + DECL_CONV_STUB(IfcBuildingElementComponent); + DECL_CONV_STUB(IfcReinforcingElement); + DECL_CONV_STUB(IfcReinforcingBar); + DECL_CONV_STUB(IfcElectricHeaterType); + DECL_CONV_STUB(IfcTShapeProfileDef); + DECL_CONV_STUB(IfcStructuralActivity); + DECL_CONV_STUB(IfcStructuralAction); + DECL_CONV_STUB(IfcDuctFittingType); + DECL_CONV_STUB(IfcCartesianTransformationOperator2D); + DECL_CONV_STUB(IfcCartesianTransformationOperator2DnonUniform); DECL_CONV_STUB(IfcVirtualElement); - DECL_CONV_STUB(IfcConstructionProductResource); - DECL_CONV_STUB(IfcSurfaceCurveSweptAreaSolid); - DECL_CONV_STUB(IfcCartesianTransformationOperator3D); - DECL_CONV_STUB(IfcCartesianTransformationOperator3DnonUniform); - DECL_CONV_STUB(IfcCrewResource); - DECL_CONV_STUB(IfcStructuralSurfaceMember); - DECL_CONV_STUB(Ifc2DCompositeCurve); - DECL_CONV_STUB(IfcRepresentationContext); - DECL_CONV_STUB(IfcGeometricRepresentationContext); - DECL_CONV_STUB(IfcFlowTreatmentDevice); DECL_CONV_STUB(IfcRightCircularCylinder); - DECL_CONV_STUB(IfcWasteTerminalType); - DECL_CONV_STUB(IfcBuildingElementComponent); - DECL_CONV_STUB(IfcBuildingElementPart); - DECL_CONV_STUB(IfcWall); - DECL_CONV_STUB(IfcWallStandardCase); + DECL_CONV_STUB(IfcOutletType); + DECL_CONV_STUB(IfcRelDecomposes); + DECL_CONV_STUB(IfcCovering); + DECL_CONV_STUB(IfcPolyline); DECL_CONV_STUB(IfcPath); - DECL_CONV_STUB(IfcDefinedSymbol); - DECL_CONV_STUB(IfcStructuralSurfaceMemberVarying); - DECL_CONV_STUB(IfcPoint); - DECL_CONV_STUB(IfcSurfaceOfRevolution); - DECL_CONV_STUB(IfcFlowTerminal); - DECL_CONV_STUB(IfcFurnishingElement); - DECL_CONV_STUB(IfcSurfaceStyleShading); - DECL_CONV_STUB(IfcSurfaceStyleRendering); - DECL_CONV_STUB(IfcCircleHollowProfileDef); + DECL_CONV_STUB(IfcElementComponent); + DECL_CONV_STUB(IfcFastener); + DECL_CONV_STUB(IfcMappedItem); + DECL_CONV_STUB(IfcRectangularPyramid); + DECL_CONV_STUB(IfcCrewResource); + DECL_CONV_STUB(IfcNamedUnit); + DECL_CONV_STUB(IfcContextDependentUnit); + DECL_CONV_STUB(IfcUnitaryEquipmentType); + DECL_CONV_STUB(IfcRoof); + DECL_CONV_STUB(IfcStructuralMember); + DECL_CONV_STUB(IfcStyleModel); + DECL_CONV_STUB(IfcStyledRepresentation); + DECL_CONV_STUB(IfcSpatialStructureElement); + DECL_CONV_STUB(IfcBuilding); + DECL_CONV_STUB(IfcConnectedFaceSet); + DECL_CONV_STUB(IfcOpenShell); + DECL_CONV_STUB(IfcFacetedBrep); + DECL_CONV_STUB(IfcConic); + DECL_CONV_STUB(IfcCoveringType); + DECL_CONV_STUB(IfcRoundedRectangleProfileDef); + DECL_CONV_STUB(IfcAirTerminalType); DECL_CONV_STUB(IfcFlowMovingDeviceType); - DECL_CONV_STUB(IfcFanType); - DECL_CONV_STUB(IfcStructuralPlanarActionVarying); - DECL_CONV_STUB(IfcProductRepresentation); - DECL_CONV_STUB(IfcStackTerminalType); - DECL_CONV_STUB(IfcReinforcingElement); - DECL_CONV_STUB(IfcReinforcingMesh); - DECL_CONV_STUB(IfcOrderAction); - DECL_CONV_STUB(IfcLightSource); - DECL_CONV_STUB(IfcLightSourceDirectional); - DECL_CONV_STUB(IfcLoop); - DECL_CONV_STUB(IfcVertexLoop); - DECL_CONV_STUB(IfcChamferEdgeFeature); + DECL_CONV_STUB(IfcCompressorType); + DECL_CONV_STUB(IfcIShapeProfileDef); + DECL_CONV_STUB(IfcAsymmetricIShapeProfileDef); + DECL_CONV_STUB(IfcControllerType); + DECL_CONV_STUB(IfcRailing); + DECL_CONV_STUB(IfcGroup); + DECL_CONV_STUB(IfcAsset); + DECL_CONV_STUB(IfcMaterialDefinitionRepresentation); + DECL_CONV_STUB(IfcRailingType); + DECL_CONV_STUB(IfcWall); + DECL_CONV_STUB(IfcStructuralPointConnection); + DECL_CONV_STUB(IfcPropertyListValue); + DECL_CONV_STUB(IfcFurnitureStandard); + DECL_CONV_STUB(IfcElectricGeneratorType); + DECL_CONV_STUB(IfcDoor); + DECL_CONV_STUB(IfcStyledItem); + DECL_CONV_STUB(IfcAnnotationOccurrence); + DECL_CONV_STUB(IfcAnnotationSymbolOccurrence); + DECL_CONV_STUB(IfcArbitraryClosedProfileDef); + DECL_CONV_STUB(IfcArbitraryProfileDefWithVoids); + DECL_CONV_STUB(IfcLine); + DECL_CONV_STUB(IfcFlowSegmentType); + DECL_CONV_STUB(IfcAirTerminalBoxType); + DECL_CONV_STUB(IfcPropertySingleValue); + DECL_CONV_STUB(IfcAlarmType); + DECL_CONV_STUB(IfcEllipseProfileDef); + DECL_CONV_STUB(IfcStair); + DECL_CONV_STUB(IfcSurfaceStyleShading); + DECL_CONV_STUB(IfcPumpType); + DECL_CONV_STUB(IfcDefinedSymbol); DECL_CONV_STUB(IfcElementComponentType); DECL_CONV_STUB(IfcFastenerType); DECL_CONV_STUB(IfcMechanicalFastenerType); - DECL_CONV_STUB(IfcScheduleTimeControl); + DECL_CONV_STUB(IfcFlowFitting); + DECL_CONV_STUB(IfcLightSourceDirectional); DECL_CONV_STUB(IfcSurfaceStyle); - DECL_CONV_STUB(IfcOpenShell); - DECL_CONV_STUB(IfcSubContractResource); - DECL_CONV_STUB(IfcSweptDiskSolid); - DECL_CONV_STUB(IfcCompositeProfileDef); - DECL_CONV_STUB(IfcTankType); - DECL_CONV_STUB(IfcSphere); - DECL_CONV_STUB(IfcPolyLoop); - DECL_CONV_STUB(IfcCableCarrierFittingType); - DECL_CONV_STUB(IfcHumidifierType); - DECL_CONV_STUB(IfcPerformanceHistory); - DECL_CONV_STUB(IfcShapeModel); - DECL_CONV_STUB(IfcTopologyRepresentation); - DECL_CONV_STUB(IfcBuilding); - DECL_CONV_STUB(IfcRoundedRectangleProfileDef); - DECL_CONV_STUB(IfcStairFlight); - DECL_CONV_STUB(IfcDistributionChamberElement); - DECL_CONV_STUB(IfcShapeRepresentation); - DECL_CONV_STUB(IfcRampFlight); - DECL_CONV_STUB(IfcBeamType); - DECL_CONV_STUB(IfcRelDecomposes); - DECL_CONV_STUB(IfcRoof); - DECL_CONV_STUB(IfcFooting); - DECL_CONV_STUB(IfcLightSourceAmbient); - DECL_CONV_STUB(IfcWindowStyle); - DECL_CONV_STUB(IfcBuildingElementProxyType); - DECL_CONV_STUB(IfcAxis2Placement3D); - DECL_CONV_STUB(IfcEdgeCurve); - DECL_CONV_STUB(IfcClosedShell); - DECL_CONV_STUB(IfcTendonAnchor); - DECL_CONV_STUB(IfcCondenserType); - DECL_CONV_STUB(IfcPipeSegmentType); - DECL_CONV_STUB(IfcPointOnSurface); - DECL_CONV_STUB(IfcAsset); - DECL_CONV_STUB(IfcLightSourcePositional); - DECL_CONV_STUB(IfcProjectionCurve); - DECL_CONV_STUB(IfcFillAreaStyleTiles); - DECL_CONV_STUB(IfcRelFillsElement); - DECL_CONV_STUB(IfcElectricMotorType); - DECL_CONV_STUB(IfcTendon); + DECL_CONV_STUB(IfcAnnotationSurface); + DECL_CONV_STUB(IfcFlowController); + DECL_CONV_STUB(IfcBuildingStorey); + DECL_CONV_STUB(IfcWorkControl); + DECL_CONV_STUB(IfcWorkSchedule); + DECL_CONV_STUB(IfcDuctSegmentType); + DECL_CONV_STUB(IfcFace); + DECL_CONV_STUB(IfcStructuralSurfaceMember); + DECL_CONV_STUB(IfcStructuralSurfaceMemberVarying); + DECL_CONV_STUB(IfcFaceSurface); + DECL_CONV_STUB(IfcCostSchedule); + DECL_CONV_STUB(IfcPlanarExtent); + DECL_CONV_STUB(IfcPlanarBox); + DECL_CONV_STUB(IfcColourSpecification); + DECL_CONV_STUB(IfcVector); + DECL_CONV_STUB(IfcBeam); + DECL_CONV_STUB(IfcColourRgb); + DECL_CONV_STUB(IfcStructuralPlanarAction); + DECL_CONV_STUB(IfcStructuralPlanarActionVarying); + DECL_CONV_STUB(IfcSite); + DECL_CONV_STUB(IfcDiscreteAccessoryType); + DECL_CONV_STUB(IfcVibrationIsolatorType); + DECL_CONV_STUB(IfcEvaporativeCoolerType); DECL_CONV_STUB(IfcDistributionChamberElementType); + DECL_CONV_STUB(IfcFeatureElementAddition); + DECL_CONV_STUB(IfcStructuredDimensionCallout); + DECL_CONV_STUB(IfcCoolingTowerType); + DECL_CONV_STUB(IfcCenterLineProfileDef); + DECL_CONV_STUB(IfcWindowStyle); + DECL_CONV_STUB(IfcLightSourceGoniometric); + DECL_CONV_STUB(IfcTransformerType); DECL_CONV_STUB(IfcMemberType); - DECL_CONV_STUB(IfcStructuralLinearAction); - DECL_CONV_STUB(IfcStructuralLinearActionVarying); - DECL_CONV_STUB(IfcProductDefinitionShape); - DECL_CONV_STUB(IfcFastener); - DECL_CONV_STUB(IfcMechanicalFastener); - DECL_CONV_STUB(IfcEvaporatorType); - DECL_CONV_STUB(IfcDiscreteAccessoryType); - DECL_CONV_STUB(IfcStructuralCurveConnection); - DECL_CONV_STUB(IfcProjectionElement); - DECL_CONV_STUB(IfcCoveringType); - DECL_CONV_STUB(IfcPumpType); - DECL_CONV_STUB(IfcPile); - DECL_CONV_STUB(IfcUnitAssignment); - DECL_CONV_STUB(IfcBoundingBox); + DECL_CONV_STUB(IfcSurfaceOfLinearExtrusion); + DECL_CONV_STUB(IfcMotorConnectionType); + DECL_CONV_STUB(IfcFlowTreatmentDeviceType); + DECL_CONV_STUB(IfcDuctSilencerType); + DECL_CONV_STUB(IfcFurnishingElementType); + DECL_CONV_STUB(IfcSystemFurnitureElementType); + DECL_CONV_STUB(IfcWasteTerminalType); + DECL_CONV_STUB(IfcBSplineCurve); + DECL_CONV_STUB(IfcBezierCurve); + DECL_CONV_STUB(IfcActuatorType); + DECL_CONV_STUB(IfcDistributionControlElement); + DECL_CONV_STUB(IfcAnnotation); DECL_CONV_STUB(IfcShellBasedSurfaceModel); - DECL_CONV_STUB(IfcFacetedBrep); - DECL_CONV_STUB(IfcTextLiteralWithExtent); - DECL_CONV_STUB(IfcElectricApplianceType); - DECL_CONV_STUB(IfcTrapeziumProfileDef); - DECL_CONV_STUB(IfcRelContainedInSpatialStructure); - DECL_CONV_STUB(IfcEdgeLoop); - DECL_CONV_STUB(IfcProject); - DECL_CONV_STUB(IfcCartesianPoint); - DECL_CONV_STUB(IfcCurveBoundedPlane); - DECL_CONV_STUB(IfcWallType); + DECL_CONV_STUB(IfcActionRequest); + DECL_CONV_STUB(IfcExtrudedAreaSolid); + DECL_CONV_STUB(IfcSystem); DECL_CONV_STUB(IfcFillAreaStyleHatching); + DECL_CONV_STUB(IfcRelVoidsElement); + DECL_CONV_STUB(IfcSurfaceCurveSweptAreaSolid); + DECL_CONV_STUB(IfcCartesianTransformationOperator3DnonUniform); + DECL_CONV_STUB(IfcCurtainWallType); DECL_CONV_STUB(IfcEquipmentStandard); + DECL_CONV_STUB(IfcFlowStorageDeviceType); DECL_CONV_STUB(IfcDiameterDimension); - DECL_CONV_STUB(IfcStructuralLoadGroup); - DECL_CONV_STUB(IfcConstructionMaterialResource); - DECL_CONV_STUB(IfcRelAggregates); - DECL_CONV_STUB(IfcBoilerType); - DECL_CONV_STUB(IfcColourSpecification); - DECL_CONV_STUB(IfcColourRgb); - DECL_CONV_STUB(IfcDoorStyle); - DECL_CONV_STUB(IfcDuctSilencerType); - DECL_CONV_STUB(IfcLightSourceGoniometric); - DECL_CONV_STUB(IfcActuatorType); + DECL_CONV_STUB(IfcSwitchingDeviceType); + DECL_CONV_STUB(IfcWindow); + DECL_CONV_STUB(IfcFlowTreatmentDevice); + DECL_CONV_STUB(IfcChillerType); + DECL_CONV_STUB(IfcRectangleHollowProfileDef); + DECL_CONV_STUB(IfcBoxedHalfSpace); + DECL_CONV_STUB(IfcAxis2Placement2D); + DECL_CONV_STUB(IfcSpaceProgram); + DECL_CONV_STUB(IfcPoint); + DECL_CONV_STUB(IfcCartesianPoint); + DECL_CONV_STUB(IfcBoundedSurface); + DECL_CONV_STUB(IfcLoop); + DECL_CONV_STUB(IfcPolyLoop); + DECL_CONV_STUB(IfcTerminatorSymbol); + DECL_CONV_STUB(IfcDimensionCurveTerminator); + DECL_CONV_STUB(IfcTrapeziumProfileDef); + DECL_CONV_STUB(IfcRepresentationContext); + DECL_CONV_STUB(IfcGeometricRepresentationContext); + DECL_CONV_STUB(IfcCurveBoundedPlane); + DECL_CONV_STUB(IfcSIUnit); + DECL_CONV_STUB(IfcStructuralReaction); + DECL_CONV_STUB(IfcStructuralPointReaction); + DECL_CONV_STUB(IfcAxis1Placement); + DECL_CONV_STUB(IfcElectricApplianceType); DECL_CONV_STUB(IfcSensorType); - DECL_CONV_STUB(IfcAirTerminalBoxType); - DECL_CONV_STUB(IfcAnnotationSurfaceOccurrence); + DECL_CONV_STUB(IfcFurnishingElement); + DECL_CONV_STUB(IfcProtectiveDeviceType); DECL_CONV_STUB(IfcZShapeProfileDef); - DECL_CONV_STUB(IfcRationalBezierCurve); - DECL_CONV_STUB(IfcCartesianTransformationOperator2D); - DECL_CONV_STUB(IfcCartesianTransformationOperator2DnonUniform); - DECL_CONV_STUB(IfcMove); - DECL_CONV_STUB(IfcCableCarrierSegmentType); - DECL_CONV_STUB(IfcElectricalElement); - DECL_CONV_STUB(IfcChillerType); - DECL_CONV_STUB(IfcReinforcingBar); - DECL_CONV_STUB(IfcCShapeProfileDef); - DECL_CONV_STUB(IfcPermit); - DECL_CONV_STUB(IfcSlabType); - DECL_CONV_STUB(IfcLampType); - DECL_CONV_STUB(IfcPlanarExtent); - DECL_CONV_STUB(IfcAlarmType); - DECL_CONV_STUB(IfcElectricFlowStorageDeviceType); - DECL_CONV_STUB(IfcEquipmentElement); + DECL_CONV_STUB(IfcScheduleTimeControl); + DECL_CONV_STUB(IfcRepresentationMap); + DECL_CONV_STUB(IfcClosedShell); + DECL_CONV_STUB(IfcBuildingElementPart); + DECL_CONV_STUB(IfcBlock); DECL_CONV_STUB(IfcLightFixtureType); - DECL_CONV_STUB(IfcCurtainWall); - DECL_CONV_STUB(IfcSlab); - DECL_CONV_STUB(IfcCurtainWallType); - DECL_CONV_STUB(IfcOutletType); - DECL_CONV_STUB(IfcCompressorType); - DECL_CONV_STUB(IfcCraneRailAShapeProfileDef); - DECL_CONV_STUB(IfcFlowSegment); - DECL_CONV_STUB(IfcSectionedSpine); - DECL_CONV_STUB(IfcElectricTimeControlType); - DECL_CONV_STUB(IfcFaceSurface); - DECL_CONV_STUB(IfcMotorConnectionType); - DECL_CONV_STUB(IfcFlowFitting); - DECL_CONV_STUB(IfcPointOnCurve); - DECL_CONV_STUB(IfcTransportElementType); + DECL_CONV_STUB(IfcOpeningElement); + DECL_CONV_STUB(IfcLightSourceSpot); + DECL_CONV_STUB(IfcTendonAnchor); + DECL_CONV_STUB(IfcElectricFlowStorageDeviceType); + DECL_CONV_STUB(IfcSphere); + DECL_CONV_STUB(IfcDamperType); + DECL_CONV_STUB(IfcProjectOrderRecord); + DECL_CONV_STUB(IfcDistributionChamberElement); + DECL_CONV_STUB(IfcMechanicalFastener); + DECL_CONV_STUB(IfcRectangularTrimmedSurface); + DECL_CONV_STUB(IfcZone); + DECL_CONV_STUB(IfcFanType); + DECL_CONV_STUB(IfcGeometricSet); + DECL_CONV_STUB(IfcFillAreaStyleTiles); DECL_CONV_STUB(IfcCableSegmentType); - DECL_CONV_STUB(IfcAnnotationSurface); - DECL_CONV_STUB(IfcCompositeCurveSegment); + DECL_CONV_STUB(IfcRelOverridesProperties); + DECL_CONV_STUB(IfcMeasureWithUnit); + DECL_CONV_STUB(IfcSlabType); DECL_CONV_STUB(IfcServiceLife); - DECL_CONV_STUB(IfcPlateType); - DECL_CONV_STUB(IfcVibrationIsolatorType); - DECL_CONV_STUB(IfcTrimmedCurve); - DECL_CONV_STUB(IfcMappedItem); - DECL_CONV_STUB(IfcDirection); - DECL_CONV_STUB(IfcBlock); - DECL_CONV_STUB(IfcProjectOrderRecord); - DECL_CONV_STUB(IfcFlowMeterType); - DECL_CONV_STUB(IfcControllerType); - DECL_CONV_STUB(IfcBeam); - DECL_CONV_STUB(IfcArbitraryOpenProfileDef); - DECL_CONV_STUB(IfcCenterLineProfileDef); - DECL_CONV_STUB(IfcTimeSeriesSchedule); - DECL_CONV_STUB(IfcRoundedEdgeFeature); - DECL_CONV_STUB(IfcIShapeProfileDef); - DECL_CONV_STUB(IfcSpaceHeaterType); - DECL_CONV_STUB(IfcFlowStorageDevice); - DECL_CONV_STUB(IfcRevolvedAreaSolid); - DECL_CONV_STUB(IfcDoor); - DECL_CONV_STUB(IfcEllipse); - DECL_CONV_STUB(IfcTubeBundleType); - DECL_CONV_STUB(IfcAngularDimension); + DECL_CONV_STUB(IfcFurnitureType); + DECL_CONV_STUB(IfcCostItem); + DECL_CONV_STUB(IfcReinforcingMesh); + DECL_CONV_STUB(IfcFacetedBrepWithVoids); + DECL_CONV_STUB(IfcGasTerminalType); + DECL_CONV_STUB(IfcPile); + DECL_CONV_STUB(IfcFillAreaStyleTileSymbolWithStyle); + DECL_CONV_STUB(IfcConstructionMaterialResource); + DECL_CONV_STUB(IfcAnnotationCurveOccurrence); + DECL_CONV_STUB(IfcDimensionCurve); + DECL_CONV_STUB(IfcGeometricCurveSet); + DECL_CONV_STUB(IfcRelAggregates); DECL_CONV_STUB(IfcFaceBasedSurfaceModel); - DECL_CONV_STUB(IfcCraneRailFShapeProfileDef); - DECL_CONV_STUB(IfcColumnType); - DECL_CONV_STUB(IfcTShapeProfileDef); DECL_CONV_STUB(IfcEnergyConversionDevice); - DECL_CONV_STUB(IfcWorkSchedule); - DECL_CONV_STUB(IfcZone); - DECL_CONV_STUB(IfcTransportElement); - DECL_CONV_STUB(IfcGeometricRepresentationSubContext); - DECL_CONV_STUB(IfcLShapeProfileDef); - DECL_CONV_STUB(IfcGeometricCurveSet); - DECL_CONV_STUB(IfcActor); - DECL_CONV_STUB(IfcOccupant); - DECL_CONV_STUB(IfcBooleanClippingResult); - DECL_CONV_STUB(IfcAnnotationFillArea); - DECL_CONV_STUB(IfcLightSourceSpot); - DECL_CONV_STUB(IfcFireSuppressionTerminalType); - DECL_CONV_STUB(IfcElectricGeneratorType); + DECL_CONV_STUB(IfcRampFlight); + DECL_CONV_STUB(IfcVertexLoop); + DECL_CONV_STUB(IfcPlate); + DECL_CONV_STUB(IfcUShapeProfileDef); + DECL_CONV_STUB(IfcFaceBound); + DECL_CONV_STUB(IfcFaceOuterBound); + DECL_CONV_STUB(IfcOneDirectionRepeatFactor); + DECL_CONV_STUB(IfcBoilerType); + DECL_CONV_STUB(IfcConstructionEquipmentResource); + DECL_CONV_STUB(IfcComplexProperty); + DECL_CONV_STUB(IfcFooting); + DECL_CONV_STUB(IfcConstructionProductResource); + DECL_CONV_STUB(IfcDerivedProfileDef); + DECL_CONV_STUB(IfcPropertyTableValue); + DECL_CONV_STUB(IfcFlowMeterType); + DECL_CONV_STUB(IfcDoorStyle); + DECL_CONV_STUB(IfcUnitAssignment); + DECL_CONV_STUB(IfcFlowTerminal); + DECL_CONV_STUB(IfcCraneRailFShapeProfileDef); + DECL_CONV_STUB(IfcFlowSegment); + DECL_CONV_STUB(IfcElementQuantity); + DECL_CONV_STUB(IfcCurtainWall); + DECL_CONV_STUB(IfcDiscreteAccessory); + DECL_CONV_STUB(IfcGrid); + DECL_CONV_STUB(IfcSanitaryTerminalType); + DECL_CONV_STUB(IfcSubedge); + DECL_CONV_STUB(IfcFilterType); + DECL_CONV_STUB(IfcTendon); + DECL_CONV_STUB(IfcStructuralLoadGroup); + DECL_CONV_STUB(IfcPresentationStyleAssignment); + DECL_CONV_STUB(IfcStructuralCurveMember); + DECL_CONV_STUB(IfcLightSourceAmbient); + DECL_CONV_STUB(IfcCondition); + DECL_CONV_STUB(IfcPort); + DECL_CONV_STUB(IfcSpace); + DECL_CONV_STUB(IfcHeatExchangerType); + DECL_CONV_STUB(IfcTankType); DECL_CONV_STUB(IfcInventory); - DECL_CONV_STUB(IfcPolyline); - DECL_CONV_STUB(IfcBoxedHalfSpace); - DECL_CONV_STUB(IfcAirTerminalType); - DECL_CONV_STUB(IfcDistributionPort); - DECL_CONV_STUB(IfcCostItem); - DECL_CONV_STUB(IfcStructuredDimensionCallout); + DECL_CONV_STUB(IfcTransportElementType); + DECL_CONV_STUB(IfcAirToAirHeatRecoveryType); + DECL_CONV_STUB(IfcStairFlight); + DECL_CONV_STUB(IfcElectricalElement); + DECL_CONV_STUB(IfcSurfaceStyleWithTextures); + DECL_CONV_STUB(IfcBoundingBox); + DECL_CONV_STUB(IfcWallType); + DECL_CONV_STUB(IfcMove); + DECL_CONV_STUB(IfcCircle); + DECL_CONV_STUB(IfcOffsetCurve2D); + DECL_CONV_STUB(IfcPointOnCurve); DECL_CONV_STUB(IfcStructuralResultGroup); - DECL_CONV_STUB(IfcOrientedEdge); + DECL_CONV_STUB(IfcSectionedSpine); + DECL_CONV_STUB(IfcSlab); + DECL_CONV_STUB(IfcVertex); + DECL_CONV_STUB(IfcVertexPoint); + DECL_CONV_STUB(IfcStructuralLinearAction); + DECL_CONV_STUB(IfcStructuralLinearActionVarying); + DECL_CONV_STUB(IfcBuildingElementProxyType); + DECL_CONV_STUB(IfcProjectionElement); + DECL_CONV_STUB(IfcConversionBasedUnit); + DECL_CONV_STUB(IfcGeometricRepresentationSubContext); + DECL_CONV_STUB(IfcAnnotationSurfaceOccurrence); + DECL_CONV_STUB(IfcRoundedEdgeFeature); + DECL_CONV_STUB(IfcElectricDistributionPoint); + DECL_CONV_STUB(IfcCableCarrierSegmentType); + DECL_CONV_STUB(IfcWallStandardCase); DECL_CONV_STUB(IfcCsgSolid); - DECL_CONV_STUB(IfcPlanarBox); - DECL_CONV_STUB(IfcMaterialDefinitionRepresentation); - DECL_CONV_STUB(IfcAsymmetricIShapeProfileDef); - DECL_CONV_STUB(IfcRepresentationMap); + DECL_CONV_STUB(IfcBeamType); + DECL_CONV_STUB(IfcAnnotationFillArea); + DECL_CONV_STUB(IfcStructuralCurveMemberVarying); + DECL_CONV_STUB(IfcPointOnSurface); + DECL_CONV_STUB(IfcOrderAction); + DECL_CONV_STUB(IfcEdgeLoop); + DECL_CONV_STUB(IfcAnnotationFillAreaOccurrence); + DECL_CONV_STUB(IfcWorkPlan); + DECL_CONV_STUB(IfcEllipse); + DECL_CONV_STUB(IfcProductDefinitionShape); + DECL_CONV_STUB(IfcProjectionCurve); + DECL_CONV_STUB(IfcElectricalCircuit); + DECL_CONV_STUB(IfcRationalBezierCurve); + DECL_CONV_STUB(IfcStructuralPointAction); + DECL_CONV_STUB(IfcPipeSegmentType); + DECL_CONV_STUB(IfcTwoDirectionRepeatFactor); + DECL_CONV_STUB(IfcShapeRepresentation); + DECL_CONV_STUB(IfcPropertySet); + DECL_CONV_STUB(IfcSurfaceStyleRendering); + DECL_CONV_STUB(IfcDistributionPort); + DECL_CONV_STUB(IfcPipeFittingType); + DECL_CONV_STUB(IfcTransportElement); + DECL_CONV_STUB(IfcAnnotationTextOccurrence); + DECL_CONV_STUB(IfcStructuralAnalysisModel); + DECL_CONV_STUB(IfcConditionCriterion); #undef DECL_CONV_STUB diff --git a/src/3rdparty/assimp/code/IFCUtil.cpp b/src/3rdparty/assimp/code/IFCUtil.cpp index 4bb4d9c1f..92e55c9ac 100644 --- a/src/3rdparty/assimp/code/IFCUtil.cpp +++ b/src/3rdparty/assimp/code/IFCUtil.cpp @@ -45,7 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER + #include "IFCUtil.h" +#include "PolyTools.h" #include "ProcessHelper.h" namespace Assimp { @@ -57,6 +59,9 @@ void TempOpening::Transform(const IfcMatrix4& mat) if(profileMesh) { profileMesh->Transform(mat); } + if(profileMesh2D) { + profileMesh2D->Transform(mat); + } extrusionDir *= IfcMatrix3(mat); } @@ -128,6 +133,122 @@ void TempMesh::Append(const TempMesh& other) } // ------------------------------------------------------------------------------------------------ +void TempMesh::RemoveDegenerates() +{ + // The strategy is simple: walk the mesh and compute normals using + // Newell's algorithm. The length of the normals gives the area + // of the polygons, which is close to zero for lines. + + std::vector<IfcVector3> normals; + ComputePolygonNormals(normals, false); + + bool drop = false; + size_t inor = 0; + + std::vector<IfcVector3>::iterator vit = verts.begin(); + for (std::vector<unsigned int>::iterator it = vertcnt.begin(); it != vertcnt.end(); ++inor) { + const unsigned int pcount = *it; + + if (normals[inor].SquareLength() < 1e-5f) { + it = vertcnt.erase(it); + vit = verts.erase(vit, vit + pcount); + + drop = true; + continue; + } + + vit += pcount; + ++it; + } + + if(drop) { + IFCImporter::LogDebug("removing degenerate faces"); + } +} + +// ------------------------------------------------------------------------------------------------ +void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals, + bool normalize, + size_t ofs) const +{ + size_t max_vcount = 0; + std::vector<unsigned int>::const_iterator begin = vertcnt.begin()+ofs, end = vertcnt.end(), iit; + for(iit = begin; iit != end; ++iit) { + max_vcount = std::max(max_vcount,static_cast<size_t>(*iit)); + } + + std::vector<IfcFloat> temp((max_vcount+2)*4); + normals.reserve( normals.size() + vertcnt.size()-ofs ); + + // `NewellNormal()` currently has a relatively strange interface and need to + // re-structure things a bit to meet them. + size_t vidx = std::accumulate(vertcnt.begin(),begin,0); + for(iit = begin; iit != end; vidx += *iit++) { + if (!*iit) { + normals.push_back(IfcVector3()); + continue; + } + for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) { + const IfcVector3& v = verts[vidx+vofs]; + temp[cnt++] = v.x; + temp[cnt++] = v.y; + temp[cnt++] = v.z; +#ifdef ASSIMP_BUILD_DEBUG + temp[cnt] = std::numeric_limits<IfcFloat>::quiet_NaN(); +#endif + ++cnt; + } + + normals.push_back(IfcVector3()); + NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]); + } + + if(normalize) { + BOOST_FOREACH(IfcVector3& n, normals) { + n.Normalize(); + } + } +} + +// ------------------------------------------------------------------------------------------------ +// Compute the normal of the last polygon in the given mesh +IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const +{ + size_t total = vertcnt.back(), vidx = verts.size() - total; + std::vector<IfcFloat> temp((total+2)*3); + for(size_t vofs = 0, cnt = 0; vofs < total; ++vofs) { + const IfcVector3& v = verts[vidx+vofs]; + temp[cnt++] = v.x; + temp[cnt++] = v.y; + temp[cnt++] = v.z; + } + IfcVector3 nor; + NewellNormal<3,3,3>(nor,total,&temp[0],&temp[1],&temp[2]); + return normalize ? nor.Normalize() : nor; +} + +// ------------------------------------------------------------------------------------------------ +void TempMesh::FixupFaceOrientation() +{ + const IfcVector3 vavg = Center(); + + std::vector<IfcVector3> normals; + ComputePolygonNormals(normals); + + size_t c = 0, ofs = 0; + BOOST_FOREACH(unsigned int cnt, vertcnt) { + if (cnt>2){ + const IfcVector3& thisvert = verts[c]; + if (normals[ofs]*(thisvert-vavg) < 0) { + std::reverse(verts.begin()+c,verts.begin()+cnt+c); + } + } + c += cnt; + ++ofs; + } +} + +// ------------------------------------------------------------------------------------------------ void TempMesh::RemoveAdjacentDuplicates() { @@ -189,11 +310,18 @@ void TempMesh::RemoveAdjacentDuplicates() base += cnt; } if(drop) { - IFCImporter::LogDebug("removed duplicate vertices"); + IFCImporter::LogDebug("removing duplicate vertices"); } } // ------------------------------------------------------------------------------------------------ +void TempMesh::Swap(TempMesh& other) +{ + vertcnt.swap(other.vertcnt); + verts.swap(other.verts); +} + +// ------------------------------------------------------------------------------------------------ bool IsTrue(const EXPRESS::BOOLEAN& in) { return (std::string)in == "TRUE" || (std::string)in == "T"; @@ -442,6 +570,7 @@ void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationO out = locm * out * s; } + } // ! IFC } // ! Assimp diff --git a/src/3rdparty/assimp/code/IFCUtil.h b/src/3rdparty/assimp/code/IFCUtil.h index f6843110c..e78d77939 100644 --- a/src/3rdparty/assimp/code/IFCUtil.h +++ b/src/3rdparty/assimp/code/IFCUtil.h @@ -61,7 +61,9 @@ namespace IFC { typedef aiColor4t<IfcFloat> IfcColor4; -// helper for std::for_each to delete all heap-allocated items in a container +// ------------------------------------------------------------------------------------------------ +// Helper for std::for_each to delete all heap-allocated items in a container +// ------------------------------------------------------------------------------------------------ template<typename T> struct delete_fun { @@ -70,26 +72,94 @@ struct delete_fun } }; + + +// ------------------------------------------------------------------------------------------------ +// Helper used during mesh construction. Aids at creating aiMesh'es out of relatively few polygons. +// ------------------------------------------------------------------------------------------------ +struct TempMesh +{ + std::vector<IfcVector3> verts; + std::vector<unsigned int> vertcnt; + + // utilities + aiMesh* ToMesh(); + void Clear(); + void Transform(const IfcMatrix4& mat); + IfcVector3 Center() const; + void Append(const TempMesh& other); + + bool IsEmpty() const { + return verts.empty() && vertcnt.empty(); + } + + void RemoveAdjacentDuplicates(); + void RemoveDegenerates(); + + void FixupFaceOrientation(); + IfcVector3 ComputeLastPolygonNormal(bool normalize = true) const; + void ComputePolygonNormals(std::vector<IfcVector3>& normals, + bool normalize = true, + size_t ofs = 0) const; + + void Swap(TempMesh& other); +}; + + // ------------------------------------------------------------------------------------------------ // Temporary representation of an opening in a wall or a floor // ------------------------------------------------------------------------------------------------ -struct TempMesh; struct TempOpening { - const IFC::IfcExtrudedAreaSolid* solid; + const IFC::IfcSolidModel* solid; IfcVector3 extrusionDir; + boost::shared_ptr<TempMesh> profileMesh; + boost::shared_ptr<TempMesh> profileMesh2D; + + // list of points generated for this opening. This is used to + // create connections between two opposing holes created + // from a single opening instance (two because walls tend to + // have two sides). If !empty(), the other side of the wall + // has already been processed. + std::vector<IfcVector3> wallPoints; + + // ------------------------------------------------------------------------------ + TempOpening() + : solid() + , extrusionDir() + , profileMesh() + { + } // ------------------------------------------------------------------------------ - TempOpening(const IFC::IfcExtrudedAreaSolid* solid,IfcVector3 extrusionDir,boost::shared_ptr<TempMesh> profileMesh) + TempOpening(const IFC::IfcSolidModel* solid,IfcVector3 extrusionDir, + boost::shared_ptr<TempMesh> profileMesh, + boost::shared_ptr<TempMesh> profileMesh2D) : solid(solid) , extrusionDir(extrusionDir) , profileMesh(profileMesh) + , profileMesh2D(profileMesh2D) { } // ------------------------------------------------------------------------------ void Transform(const IfcMatrix4& mat); // defined later since TempMesh is not complete yet + + + + // ------------------------------------------------------------------------------ + // Helper to sort openings by distance from a given base point + struct DistanceSorter { + + DistanceSorter(const IfcVector3& base) : base(base) {} + + bool operator () (const TempOpening& a, const TempOpening& b) const { + return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength(); + } + + IfcVector3 base; + }; }; @@ -100,7 +170,7 @@ struct ConversionData { ConversionData(const STEP::DB& db, const IFC::IfcProject& proj, aiScene* out,const IFCImporter::Settings& settings) : len_scale(1.0) - , angle_scale(1.0) + , angle_scale(-1.0) , db(db) , proj(proj) , out(out) @@ -138,8 +208,11 @@ struct ConversionData // for later processing by a parent, which is a wall. std::vector<TempOpening>* apply_openings; std::vector<TempOpening>* collect_openings; + + std::set<uint64_t> already_processed; }; + // ------------------------------------------------------------------------------------------------ // Binary predicate to compare vectors with a given, quadratic epsilon. // ------------------------------------------------------------------------------------------------ @@ -155,26 +228,21 @@ struct FuzzyVectorCompare { // ------------------------------------------------------------------------------------------------ -// Helper used during mesh construction. Aids at creating aiMesh'es out of relatively few polygons. +// Ordering predicate to totally order R^2 vectors first by x and then by y // ------------------------------------------------------------------------------------------------ -struct TempMesh -{ - std::vector<IfcVector3> verts; - std::vector<unsigned int> vertcnt; - - // utilities - aiMesh* ToMesh(); - void Clear(); - void Transform(const IfcMatrix4& mat); - IfcVector3 Center() const; - void Append(const TempMesh& other); - void RemoveAdjacentDuplicates(); +struct XYSorter { + + // sort first by X coordinates, then by Y coordinates + bool operator () (const IfcVector2&a, const IfcVector2& b) const { + if (a.x == b.x) { + return a.y < b.y; + } + return a.x < b.x; + } }; - - // conversion routines for common IFC entities, implemented in IFCUtil.cpp void ConvertColor(aiColor4D& out, const IfcColourRgb& in); void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base); @@ -198,9 +266,41 @@ bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, ConversionData& conv); // IFCGeometry.cpp +IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut); bool ProcessRepresentationItem(const IfcRepresentationItem& item, std::vector<unsigned int>& mesh_indices, ConversionData& conv); void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/); +void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, + ConversionData& conv); + +void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result, + ConversionData& conv, bool collect_openings); + +// IFCBoolean.cpp + +void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv); +void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result, + const TempMesh& first_operand, + ConversionData& conv); + +void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, + const TempMesh& first_operand, + ConversionData& conv); +void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result, + const TempMesh& first_operand, + ConversionData& conv); + + +// IFCOpenings.cpp + +bool GenerateOpenings(std::vector<TempOpening>& openings, + const std::vector<IfcVector3>& nors, + TempMesh& curmesh, + bool check_intersection, + bool generate_connection_geometry, + const IfcVector3& wall_extrusion_axis = IfcVector3(0,1,0)); + + // IFCCurve.cpp @@ -265,7 +365,7 @@ public: // and append the result to the mesh virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const; -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG // check if a particular parameter value lies within the well-defined range bool InRange(IfcFloat) const; #endif @@ -304,8 +404,8 @@ public: using Curve::SampleDiscrete; }; - - +// IfcProfile.cpp +bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv); } } diff --git a/src/3rdparty/assimp/code/IRRLoader.cpp b/src/3rdparty/assimp/code/IRRLoader.cpp index 567293a07..4e1296d0e 100644 --- a/src/3rdparty/assimp/code/IRRLoader.cpp +++ b/src/3rdparty/assimp/code/IRRLoader.cpp @@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" +#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER + #include "IRRLoader.h" #include "ParsingUtils.h" #include "fast_atof.h" @@ -1471,3 +1473,5 @@ void IRRImporter::InternReadFile( const std::string& pFile, */ return; } + +#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER diff --git a/src/3rdparty/assimp/code/IRRMeshLoader.cpp b/src/3rdparty/assimp/code/IRRMeshLoader.cpp index 85e500afd..20e5438d9 100644 --- a/src/3rdparty/assimp/code/IRRMeshLoader.cpp +++ b/src/3rdparty/assimp/code/IRRMeshLoader.cpp @@ -43,6 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" +#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER + #include "IRRMeshLoader.h" #include "ParsingUtils.h" #include "fast_atof.h" @@ -509,3 +511,5 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile, delete reader; AI_DEBUG_INVALIDATE_PTR(reader); } + +#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER diff --git a/src/3rdparty/assimp/code/IRRShared.cpp b/src/3rdparty/assimp/code/IRRShared.cpp index e21fb72b0..197c3df99 100644 --- a/src/3rdparty/assimp/code/IRRShared.cpp +++ b/src/3rdparty/assimp/code/IRRShared.cpp @@ -45,6 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" +//This section should be excluded only if both the Irrlicht AND the Irrlicht Mesh importers were omitted. +#if !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER)) + #include "IRRShared.h" #include "ParsingUtils.h" #include "fast_atof.h" @@ -494,3 +497,5 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) DefaultLogger::get()->error("IRRMESH: Unexpected end of file. Material is not complete"); return mat; } + +#endif // !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER)) diff --git a/src/3rdparty/assimp/code/Importer.cpp b/src/3rdparty/assimp/code/Importer.cpp index 34ade2d06..ea81f4972 100644 --- a/src/3rdparty/assimp/code/Importer.cpp +++ b/src/3rdparty/assimp/code/Importer.cpp @@ -197,6 +197,7 @@ Importer::Importer(const Importer &other) pimpl->mIntProperties = other.pimpl->mIntProperties; pimpl->mFloatProperties = other.pimpl->mFloatProperties; pimpl->mStringProperties = other.pimpl->mStringProperties; + pimpl->mMatrixProperties = other.pimpl->mMatrixProperties; } // ------------------------------------------------------------------------------------------------ @@ -232,7 +233,7 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp) for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) { -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG if (IsExtensionSupported(*it)) { DefaultLogger::get()->warn("The file extension " + *it + " is already in use"); } @@ -558,7 +559,7 @@ void WriteLogOpening(const std::string& file) << "<unknown compiler>" #endif -#ifndef NDEBUG +#ifdef ASSIMP_BUILD_DEBUG << " debug" #endif @@ -749,10 +750,10 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) } } #endif // no validation -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG if (pimpl->bExtraVerbose) { -#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS +#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS DefaultLogger::get()->error("Verbose Import is not available due to build settings"); #endif // no validation pFlags |= aiProcess_ValidateDataStructure; @@ -783,9 +784,9 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) if( !pimpl->mScene) { break; } -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG -#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS +#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS continue; #endif // no validation @@ -938,6 +939,16 @@ void Importer::SetPropertyString(const char* szName, const std::string& value, } // ------------------------------------------------------------------------------------------------ +// Set a configuration property +void Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value, + bool* bWasExisting /*= NULL*/) +{ + ASSIMP_BEGIN_EXCEPTION_REGION(); + SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value,bWasExisting); + ASSIMP_END_EXCEPTION_REGION(void); +} + +// ------------------------------------------------------------------------------------------------ // Get a configuration property int Importer::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const @@ -955,13 +966,21 @@ float Importer::GetPropertyFloat(const char* szName, // ------------------------------------------------------------------------------------------------ // Get a configuration property -const std::string& Importer::GetPropertyString(const char* szName, +const std::string Importer::GetPropertyString(const char* szName, const std::string& iErrorReturn /*= ""*/) const { return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn); } // ------------------------------------------------------------------------------------------------ +// Get a configuration property +const aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, + const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const +{ + return GetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties,szName,iErrorReturn); +} + +// ------------------------------------------------------------------------------------------------ // Get the memory requirements of a single node inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode) { diff --git a/src/3rdparty/assimp/code/Importer.h b/src/3rdparty/assimp/code/Importer.h index 700bb3250..f2a7c524f 100644 --- a/src/3rdparty/assimp/code/Importer.h +++ b/src/3rdparty/assimp/code/Importer.h @@ -63,11 +63,12 @@ public: // Data type to store the key hash typedef unsigned int KeyType; - // typedefs for our three configuration maps. + // typedefs for our four configuration maps. // We don't need more, so there is no need for a generic solution typedef std::map<KeyType, int> IntPropertyMap; typedef std::map<KeyType, float> FloatPropertyMap; typedef std::map<KeyType, std::string> StringPropertyMap; + typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap; public: @@ -100,6 +101,9 @@ public: /** List of string properties */ StringPropertyMap mStringProperties; + /** List of Matrix properties */ + MatrixPropertyMap mMatrixProperties; + /** Used for testing - extra verbose mode causes the ValidateDataStructure-Step * to be executed before and after every single postprocess step */ bool bExtraVerbose; @@ -135,14 +139,15 @@ public: ImporterPimpl::IntPropertyMap ints; ImporterPimpl::FloatPropertyMap floats; ImporterPimpl::StringPropertyMap strings; + ImporterPimpl::MatrixPropertyMap matrices; bool operator == (const PropertyMap& prop) const { // fixme: really isocpp? gcc complains - return ints == prop.ints && floats == prop.floats && strings == prop.strings; + return ints == prop.ints && floats == prop.floats && strings == prop.strings && matrices == prop.matrices; } bool empty () const { - return ints.empty() && floats.empty() && strings.empty(); + return ints.empty() && floats.empty() && strings.empty() && matrices.empty(); } }; //! @endcond diff --git a/src/3rdparty/assimp/code/ImporterRegistry.cpp b/src/3rdparty/assimp/code/ImporterRegistry.cpp index f715073c8..7b72c5eb6 100644 --- a/src/3rdparty/assimp/code/ImporterRegistry.cpp +++ b/src/3rdparty/assimp/code/ImporterRegistry.cpp @@ -140,7 +140,7 @@ corresponding preprocessor flag to selectively disable formats. # include "LWSLoader.h" #endif #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER -# include "OgreImporter.hpp" +# include "OgreImporter.h" #endif #ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER # include "MS3DLoader.h" @@ -160,12 +160,12 @@ corresponding preprocessor flag to selectively disable formats. #ifndef ASSIMP_BUILD_NO_IFC_IMPORTER # include "IFCLoader.h" #endif -#ifndef ASSIMP_BUILD_NO_M3_IMPORTER -# include "M3Importer.h" -#endif #ifndef ASSIMP_BUILD_NO_XGL_IMPORTER # include "XGLLoader.h" #endif +#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER +# include "FBXImporter.h" +#endif namespace Assimp { @@ -285,12 +285,12 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) #if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER) out.push_back( new IFCImporter() ); #endif -#if ( !defined ASSIMP_BUILD_NO_M3_IMPORTER ) - out.push_back( new M3::M3Importer() ); -#endif #if ( !defined ASSIMP_BUILD_NO_XGL_IMPORTER ) out.push_back( new XGLImporter() ); #endif +#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER ) + out.push_back( new FBXImporter() ); +#endif } } diff --git a/src/3rdparty/assimp/code/LWOAnimation.cpp b/src/3rdparty/assimp/code/LWOAnimation.cpp index 4520a87e0..ff7270267 100644 --- a/src/3rdparty/assimp/code/LWOAnimation.cpp +++ b/src/3rdparty/assimp/code/LWOAnimation.cpp @@ -49,6 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" #if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER) && (!defined ASSIMP_BUILD_NO_LWS_IMPORTER) +#include <functional> + // internal headers #include "LWOFileData.h" @@ -448,8 +450,8 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out, if ((*cur_x).time == (*cur_y).time && (*cur_x).time == (*cur_z).time ) { - // we have a keyframe for all of them defined .. great, - // we don't need to fucking interpolate here ... + // we have a keyframe for all of them defined .. this means + // we don't need to interpolate here. fill.mTime = (*cur_x).time; fill.mValue.x = (*cur_x).value; diff --git a/src/3rdparty/assimp/code/LWOLoader.cpp b/src/3rdparty/assimp/code/LWOLoader.cpp index a161db16e..5e5aa8351 100644 --- a/src/3rdparty/assimp/code/LWOLoader.cpp +++ b/src/3rdparty/assimp/code/LWOLoader.cpp @@ -294,7 +294,7 @@ void LWOImporter::InternReadFile( const std::string& pFile, unsigned int vUVChannelIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS]; unsigned int vVColorIndices[AI_MAX_NUMBER_OF_COLOR_SETS]; -#if _DEBUG +#ifdef ASSIMP_BUILD_DEBUG for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui ) { vUVChannelIndices[mui] = UINT_MAX; } @@ -467,6 +467,10 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& for (; begin != end; ++begin) { aiFace& face = *begin; + if(face.mNumIndices < 3) { + continue; + } + // LWO doc: "the normal is defined as the cross product of the first and last edges" aiVector3D* pV1 = mesh->mVertices + face.mIndices[0]; aiVector3D* pV2 = mesh->mVertices + face.mIndices[1]; @@ -1292,6 +1296,11 @@ void LWOImporter::LoadLWO2File() uint8_t* const next = mFileBuffer+head->length; unsigned int iUnnamed = 0; + if(!head->length) { + mFileBuffer = next; + continue; + } + switch (head->type) { // new layer diff --git a/src/3rdparty/assimp/code/LWOMaterial.cpp b/src/3rdparty/assimp/code/LWOMaterial.cpp index 9bccad3a4..70da0d675 100644 --- a/src/3rdparty/assimp/code/LWOMaterial.cpp +++ b/src/3rdparty/assimp/code/LWOMaterial.cpp @@ -167,19 +167,21 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex // The older LWOB format does not use indirect references to clips. // The file name of a texture is directly specified in the tex chunk. if (mIsLWO2) { - // find the corresponding clip - ClipList::iterator clip = mClips.begin(); + // find the corresponding clip (take the last one if multiple + // share the same index) + ClipList::iterator end = mClips.end(), candidate = end; temp = (*it).mClipIdx; - for (ClipList::iterator end = mClips.end(); clip != end; ++clip) { - if ((*clip).idx == temp) - break; + for (ClipList::iterator clip = mClips.begin(); clip != end; ++clip) { + if ((*clip).idx == temp) { + candidate = clip; + } } - if (mClips.end() == clip) { + if (candidate == end) { DefaultLogger::get()->error("LWO2: Clip index is out of bounds"); temp = 0; - // fixme: appearently some LWO files shipping with Doom3 don't + // fixme: apparently some LWO files shipping with Doom3 don't // have clips at all ... check whether that's true or whether // it's a bug in the loader. @@ -188,16 +190,16 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex //continue; } else { - if (Clip::UNSUPPORTED == (*clip).type) { + if (Clip::UNSUPPORTED == (*candidate).type) { DefaultLogger::get()->error("LWO2: Clip type is not supported"); continue; } - AdjustTexturePath((*clip).path); - s.Set((*clip).path); + AdjustTexturePath((*candidate).path); + s.Set((*candidate).path); // Additional image settings int flags = 0; - if ((*clip).negate) { + if ((*candidate).negate) { flags |= aiTextureFlags_Invert; } pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur)); diff --git a/src/3rdparty/assimp/code/LWSLoader.cpp b/src/3rdparty/assimp/code/LWSLoader.cpp index 7652b5b13..20d62569c 100644 --- a/src/3rdparty/assimp/code/LWSLoader.cpp +++ b/src/3rdparty/assimp/code/LWSLoader.cpp @@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AssimpPCH.h" +#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER #include "LWSLoader.h" #include "ParsingUtils.h" @@ -123,6 +124,7 @@ void LWS::Element::Parse (const char*& buffer) // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer LWSImporter::LWSImporter() +: noSkeletonMesh() { // nothing to do here } @@ -177,6 +179,8 @@ void LWSImporter::SetupProperties(const Importer* pImp) if (last < first) { std::swap(last,first); } + + noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; } // ------------------------------------------------------------------------------------------------ @@ -460,7 +464,7 @@ std::string LWSImporter::FindLWOFile(const std::string& in) std::string tmp; if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/') { - tmp = in[0] + ":\\" + in.substr(2); + tmp = in[0] + (":\\" + in.substr(2)); } else tmp = in; @@ -476,11 +480,12 @@ std::string LWSImporter::FindLWOFile(const std::string& in) // <folder>\Scenes\<hh>\<*>.lws // where <hh> is optional. - std::string test = ".." + io->getOsSeparator() + tmp; - if (io->Exists(test)) + std::string test = ".." + (io->getOsSeparator() + tmp); + if (io->Exists(test)) { return test; + } - test = ".." + io->getOsSeparator() + test; + test = ".." + (io->getOsSeparator() + test); if (io->Exists(test)) { return test; } @@ -908,10 +913,12 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene, if (!pScene->mNumMeshes || !pScene->mNumMaterials) { pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; - if (pScene->mNumAnimations) { + if (pScene->mNumAnimations && !noSkeletonMesh) { // construct skeleton mesh SkeletonMeshBuilder builder(pScene); } } } + +#endif // !! ASSIMP_BUILD_NO_LWS_IMPORTER diff --git a/src/3rdparty/assimp/code/LWSLoader.h b/src/3rdparty/assimp/code/LWSLoader.h index 2d969d79d..06ca34c33 100644 --- a/src/3rdparty/assimp/code/LWSLoader.h +++ b/src/3rdparty/assimp/code/LWSLoader.h @@ -233,6 +233,8 @@ private: IOSystem* io; double first,last,fps; + + bool noSkeletonMesh; }; } // end of namespace Assimp diff --git a/src/3rdparty/assimp/code/LimitBoneWeightsProcess.h b/src/3rdparty/assimp/code/LimitBoneWeightsProcess.h index 61fdda620..942c2ceb5 100644 --- a/src/3rdparty/assimp/code/LimitBoneWeightsProcess.h +++ b/src/3rdparty/assimp/code/LimitBoneWeightsProcess.h @@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BaseProcess.h" struct aiMesh; + class LimitBoneWeightsTest; namespace Assimp @@ -69,7 +70,7 @@ namespace Assimp * The other weights on this bone are then renormalized to assure the sum weight * to be 1. */ -class LimitBoneWeightsProcess : public BaseProcess +class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess { public: diff --git a/src/3rdparty/assimp/code/LineSplitter.h b/src/3rdparty/assimp/code/LineSplitter.h index 9a6148f44..03e54cfbe 100644 --- a/src/3rdparty/assimp/code/LineSplitter.h +++ b/src/3rdparty/assimp/code/LineSplitter.h @@ -103,13 +103,10 @@ public: swallow = false; return *this; } - if (!*this) { throw std::logic_error("End of file, no more lines to be retrieved."); } - char s; - cur.clear(); while(stream.GetRemainingSize() && (s = stream.GetI1(),1)) { if (s == '\n' || s == '\r') { @@ -124,7 +121,6 @@ public: if (stream.GetRemainingSize() && (s == '\r' && stream.GetI1() != '\n')) { stream.IncPtr(-1); } - if (trim) { while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\t')); if (stream.GetRemainingSize()) { @@ -132,12 +128,10 @@ public: } } } - break; } cur += s; } - ++idx; return *this; } @@ -174,7 +168,9 @@ public: SkipSpaces(&s); for(size_t i = 0; i < N; ++i) { if(IsLineEnd(*s)) { + throw std::range_error("Token count out of range, EOL reached"); + } tokens[i] = s; diff --git a/src/3rdparty/assimp/code/LogAux.h b/src/3rdparty/assimp/code/LogAux.h index 2c8431adc..4c7de04e6 100644 --- a/src/3rdparty/assimp/code/LogAux.h +++ b/src/3rdparty/assimp/code/LogAux.h @@ -89,7 +89,7 @@ public: } // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 -#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) // ------------------------------------------------------------------------------------------------ static void LogWarn (const char* message) { diff --git a/src/3rdparty/assimp/code/MD5Loader.cpp b/src/3rdparty/assimp/code/MD5Loader.cpp index 0107d7158..65911f728 100644 --- a/src/3rdparty/assimp/code/MD5Loader.cpp +++ b/src/3rdparty/assimp/code/MD5Loader.cpp @@ -187,7 +187,6 @@ void MD5Importer::LoadFileIntoMemory (IOStream* file) ai_assert(fileSize); // allocate storage and copy the contents of the file to a memory buffer - pScene = pScene; mBuffer = new char[fileSize+1]; file->Read( (void*)mBuffer, 1, fileSize); iLineNumber = 1; diff --git a/src/3rdparty/assimp/code/MDLMaterialLoader.cpp b/src/3rdparty/assimp/code/MDLMaterialLoader.cpp index 569db29c3..3d32420e1 100644 --- a/src/3rdparty/assimp/code/MDLMaterialLoader.cpp +++ b/src/3rdparty/assimp/code/MDLMaterialLoader.cpp @@ -787,7 +787,6 @@ void MDLImporter::SkipSkinLump_3DGS_MDL7( } // ------------------------------------------------------------------------------------------------ -// What the fuck does this function do? Can't remember void MDLImporter::ParseSkinLump_3DGS_MDL7( const unsigned char* szCurrent, const unsigned char** szCurrentOut, diff --git a/src/3rdparty/assimp/code/MS3DLoader.cpp b/src/3rdparty/assimp/code/MS3DLoader.cpp index 7c594f41e..c1a4a8dbf 100644 --- a/src/3rdparty/assimp/code/MS3DLoader.cpp +++ b/src/3rdparty/assimp/code/MS3DLoader.cpp @@ -563,7 +563,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile, } // ... add dummy nodes under a single root, each holding a reference to one - // mesh. If we didn't do this, we'd loose the group name. + // mesh. If we didn't do this, we'd lose the group name. aiNode* rt = pScene->mRootNode = new aiNode("<MS3DRoot>"); #ifdef ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH diff --git a/src/3rdparty/assimp/code/MaterialSystem.cpp b/src/3rdparty/assimp/code/MaterialSystem.cpp index e33b8f1fa..5223c9bae 100644 --- a/src/3rdparty/assimp/code/MaterialSystem.cpp +++ b/src/3rdparty/assimp/code/MaterialSystem.cpp @@ -102,7 +102,7 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat, } // data is given in floats, simply copy it - unsigned int iWrite; + unsigned int iWrite = 0; if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) { iWrite = prop->mDataLength / sizeof(float); if (pMax) { @@ -175,7 +175,7 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat, } // data is given in ints, simply copy it - unsigned int iWrite; + unsigned int iWrite = 0; if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) { iWrite = prop->mDataLength / sizeof(int32_t); if (pMax) { @@ -248,6 +248,18 @@ aiReturn aiGetMaterialColor(const aiMaterial* pMat, } // ------------------------------------------------------------------------------------------------ +// Get a aiUVTransform (4 floats) from the material +aiReturn aiGetMaterialUVTransform(const aiMaterial* pMat, + const char* pKey, + unsigned int type, + unsigned int index, + aiUVTransform* pOut) +{ + unsigned int iMax = 4; + return aiGetMaterialFloatArray(pMat,pKey,type,index,(float*)pOut,&iMax); +} + +// ------------------------------------------------------------------------------------------------ // Get a string from the material aiReturn aiGetMaterialString(const aiMaterial* pMat, const char* pKey, diff --git a/src/3rdparty/assimp/code/MemoryIOWrapper.h b/src/3rdparty/assimp/code/MemoryIOWrapper.h index 215a46486..910843a8d 100644 --- a/src/3rdparty/assimp/code/MemoryIOWrapper.h +++ b/src/3rdparty/assimp/code/MemoryIOWrapper.h @@ -53,12 +53,20 @@ class MemoryIOStream : public IOStream { //friend class MemoryIOSystem; public: - MemoryIOStream (const uint8_t* buff, size_t len) - : buffer (buff), length(len), pos((size_t)0) { + MemoryIOStream (const uint8_t* buff, size_t len, bool own = false) + : buffer (buff) + , length(len) + , pos((size_t)0) + , own(own) + { } public: + ~MemoryIOStream () { + if(own) { + delete[] buffer; + } } // ------------------------------------------------------------------- @@ -124,6 +132,7 @@ public: private: const uint8_t* buffer; size_t length,pos; + bool own; }; // --------------------------------------------------------------------------- diff --git a/src/3rdparty/assimp/code/NDOLoader.cpp b/src/3rdparty/assimp/code/NDOLoader.cpp index af10a0738..65306b396 100644 --- a/src/3rdparty/assimp/code/NDOLoader.cpp +++ b/src/3rdparty/assimp/code/NDOLoader.cpp @@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AssimpPCH.h" -#ifndef AI_BUILD_NO_NDO_IMPORTER +#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER #include "NDOLoader.h" using namespace Assimp; diff --git a/src/3rdparty/assimp/code/ObjExporter.cpp b/src/3rdparty/assimp/code/ObjExporter.cpp index b5dbb07a5..0499031e9 100644 --- a/src/3rdparty/assimp/code/ObjExporter.cpp +++ b/src/3rdparty/assimp/code/ObjExporter.cpp @@ -59,10 +59,16 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene // we're still here - export successfully completed. Write both the main OBJ file and the material script { boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output .obj file: " + std::string(pFile)); + } outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1); } { boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName())); + } outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1); } } @@ -146,6 +152,9 @@ void ObjExporter :: WriteMaterialFile() if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_SPECULAR,c)) { mOutputMat << "ks " << c.r << " " << c.g << " " << c.b << endl; } + if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_EMISSIVE,c)) { + mOutputMat << "ke " << c.r << " " << c.g << " " << c.b << endl; + } float o; if(AI_SUCCESS == mat->Get(AI_MATKEY_OPACITY,o)) { @@ -193,6 +202,7 @@ void ObjExporter :: WriteGeometryFile() AddNode(pScene->mRootNode,mBase); // write vertex positions + vpMap.getVectors(vp); mOutput << "# " << vp.size() << " vertex positions" << endl; BOOST_FOREACH(const aiVector3D& v, vp) { mOutput << "v " << v.x << " " << v.y << " " << v.z << endl; @@ -200,6 +210,7 @@ void ObjExporter :: WriteGeometryFile() mOutput << endl; // write uv coordinates + vtMap.getVectors(vt); mOutput << "# " << vt.size() << " UV coordinates" << endl; BOOST_FOREACH(const aiVector3D& v, vt) { mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl; @@ -207,6 +218,7 @@ void ObjExporter :: WriteGeometryFile() mOutput << endl; // write vertex normals + vnMap.getVectors(vn); mOutput << "# " << vn.size() << " vertex normals" << endl; BOOST_FOREACH(const aiVector3D& v, vn) { mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl; @@ -246,6 +258,31 @@ void ObjExporter :: WriteGeometryFile() } } + + + + +int ObjExporter::vecIndexMap::getIndex(const aiVector3D& vec) +{ + vecIndexMap::dataType::iterator vertIt = vecMap.find(vec); + if(vertIt != vecMap.end()){// vertex already exists, so reference it + return vertIt->second; + } + vecMap[vec] = mNextIndex; + int ret = mNextIndex; + mNextIndex++; + return ret; +} + +void ObjExporter::vecIndexMap::getVectors( std::vector<aiVector3D>& vecs ) +{ + vecs.resize(vecMap.size()); + for(vecIndexMap::dataType::iterator it = vecMap.begin(); it != vecMap.end(); it++){ + vecs[it->second-1] = it->first; + } +} + + // ------------------------------------------------------------------------------------------------ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) { @@ -256,6 +293,7 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri mesh.matname = GetMaterialName(m->mMaterialIndex); mesh.faces.resize(m->mNumFaces); + for(unsigned int i = 0; i < m->mNumFaces; ++i) { const aiFace& f = m->mFaces[i]; @@ -275,21 +313,22 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri for(unsigned int a = 0; a < f.mNumIndices; ++a) { const unsigned int idx = f.mIndices[a]; - // XXX need a way to check if this is an unique vertex or if we had it already, - // in which case we should instead reference the previous occurrence. - ai_assert(m->mVertices); - vp.push_back( mat * m->mVertices[idx] ); - face.indices[a].vp = vp.size(); + aiVector3D vert = mat * m->mVertices[idx]; + face.indices[a].vp = vpMap.getIndex(vert); if (m->mNormals) { - vn.push_back( m->mNormals[idx] ); + face.indices[a].vn = vnMap.getIndex(m->mNormals[idx]); + } + else{ + face.indices[a].vn = 0; } - face.indices[a].vn = vn.size(); if (m->mTextureCoords[0]) { - vt.push_back( m->mTextureCoords[0][idx] ); + face.indices[a].vt = vtMap.getIndex(m->mTextureCoords[0][idx]); + } + else{ + face.indices[a].vt = 0; } - face.indices[a].vt = vt.size(); } } } diff --git a/src/3rdparty/assimp/code/ObjExporter.h b/src/3rdparty/assimp/code/ObjExporter.h index 07243a1e1..4efd85636 100644 --- a/src/3rdparty/assimp/code/ObjExporter.h +++ b/src/3rdparty/assimp/code/ObjExporter.h @@ -112,6 +112,36 @@ private: const aiScene* const pScene; std::vector<aiVector3D> vp, vn, vt; + + + struct aiVectorCompare + { + bool operator() (const aiVector3D& a, const aiVector3D& b) const + { + if(a.x < b.x) return true; + if(a.x > b.x) return false; + if(a.y < b.y) return true; + if(a.y > b.y) return false; + if(a.z < b.z) return true; + return false; + } + }; + + class vecIndexMap + { + int mNextIndex; + typedef std::map<aiVector3D, int, aiVectorCompare> dataType; + dataType vecMap; + public: + + vecIndexMap():mNextIndex(1) + {} + + int getIndex(const aiVector3D& vec); + void getVectors( std::vector<aiVector3D>& vecs ); + }; + + vecIndexMap vpMap, vnMap, vtMap; std::vector<MeshInstance> meshes; // this endl() doesn't flush() the stream diff --git a/src/3rdparty/assimp/code/ObjFileData.h b/src/3rdparty/assimp/code/ObjFileData.h index fce2be650..6067e21e7 100644 --- a/src/3rdparty/assimp/code/ObjFileData.h +++ b/src/3rdparty/assimp/code/ObjFileData.h @@ -156,9 +156,26 @@ struct Material aiString texture; aiString textureSpecular; aiString textureAmbient; + aiString textureEmissive; aiString textureBump; + aiString textureNormal; aiString textureSpecularity; aiString textureOpacity; + aiString textureDisp; + enum TextureType + { + TextureDiffuseType = 0, + TextureSpecularType, + TextureAmbientType, + TextureEmissiveType, + TextureBumpType, + TextureNormalType, + TextureSpecularityType, + TextureOpacityType, + TextureDispType, + TextureTypeCount + }; + bool clamp[TextureTypeCount]; //! Ambient color aiColor3D ambient; @@ -166,6 +183,8 @@ struct Material aiColor3D diffuse; //! Specular color aiColor3D specular; + //! Emissive color + aiColor3D emissive; //! Alpha value float alpha; //! Shineness factor @@ -184,6 +203,10 @@ struct Material , ior (1.f) { // empty + for (size_t i = 0; i < TextureTypeCount; ++i) + { + clamp[i] = false; + } } // Destructor @@ -267,7 +290,7 @@ struct Model //! Active group std::string m_strActiveGroup; //! Vector with generated texture coordinates - std::vector<aiVector2D> m_TextureCoord; + std::vector<aiVector3D> m_TextureCoord; //! Current mesh instance Mesh *m_pCurrentMesh; //! Vector with stored meshes @@ -275,19 +298,20 @@ struct Model //! Material map std::map<std::string, Material*> m_MaterialMap; - //! \brief Default constructor + //! \brief The default class constructor Model() : m_ModelName(""), m_pCurrent(NULL), m_pCurrentMaterial(NULL), m_pDefaultMaterial(NULL), + m_pGroupFaceIDs(NULL), m_strActiveGroup(""), m_pCurrentMesh(NULL) { // empty } - //! \brief Destructor + //! \brief The class destructor ~Model() { // Clear all stored object instances @@ -310,7 +334,7 @@ struct Model m_Groups.clear(); for ( std::map<std::string, Material*>::iterator it = m_MaterialMap.begin(); it != m_MaterialMap.end(); ++it ) { -// delete it->second; + delete it->second; } } }; diff --git a/src/3rdparty/assimp/code/ObjFileImporter.cpp b/src/3rdparty/assimp/code/ObjFileImporter.cpp index 7344188c3..97781aff4 100644 --- a/src/3rdparty/assimp/code/ObjFileImporter.cpp +++ b/src/3rdparty/assimp/code/ObjFileImporter.cpp @@ -60,6 +60,7 @@ static const aiImporterDesc desc = { "obj" }; +static const unsigned int ObjMinSize = 16; namespace Assimp { @@ -80,12 +81,8 @@ ObjFileImporter::ObjFileImporter() : // Destructor. ObjFileImporter::~ObjFileImporter() { - // Release root object instance - if (NULL != m_pRootObject) - { - delete m_pRootObject; - m_pRootObject = NULL; - } + delete m_pRootObject; + m_pRootObject = NULL; } // ------------------------------------------------------------------------------------------------ @@ -118,13 +115,15 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, // Read file into memory const std::string mode = "rb"; boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode)); - if (NULL == file.get()) - throw DeadlyImportError( "Failed to open file " + pFile + "."); + if( !file.get() ) { + throw DeadlyImportError( "Failed to open file " + pFile + "." ); + } // Get the file-size and validate it, throwing an exception when fails size_t fileSize = file->FileSize(); - if( fileSize < 16) + if( fileSize < ObjMinSize ) { throw DeadlyImportError( "OBJ-file is too small."); + } // Allocate buffer and read file into it TextFileToBuffer(file.get(),m_Buffer); @@ -153,10 +152,10 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, // ------------------------------------------------------------------------------------------------ // Create the data from parsed obj-file -void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene) -{ - if (0L == pModel) - return; +void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene) { + if( 0L == pModel ) { + return; + } // Create the root node of the scene pScene->mRootNode = new aiNode; @@ -167,15 +166,15 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene } else { - // This is an error, so break down the application + // This is a fatal error, so break down the application ai_assert(false); - } + } // Create nodes for the whole scene std::vector<aiMesh*> MeshArray; for (size_t index = 0; index < pModel->m_Objects.size(); index++) { - createNodes(pModel, pModel->m_Objects[ index ], index, pScene->mRootNode, pScene, MeshArray); + createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray); } // Create mesh pointer buffer for this scene @@ -195,13 +194,13 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene // ------------------------------------------------------------------------------------------------ // Creates all nodes of the model aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject, - unsigned int /*uiMeshIndex*/, aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray ) { ai_assert( NULL != pModel ); - if ( NULL == pObject ) - return NULL; + if( NULL == pObject ) { + return NULL; + } // Store older mesh size to be able to computes mesh offsets for new mesh instances const size_t oldMeshSize = MeshArray.size(); @@ -210,8 +209,9 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile pNode->mName = pObject->m_strObjName; // If we have a parent node, store it - if (pParent != NULL) - appendChildToParentNode(pParent, pNode); + if( pParent != NULL ) { + appendChildToParentNode( pParent, pNode ); + } for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ ) { @@ -265,8 +265,9 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel, { // Checking preconditions ai_assert( NULL != pModel ); - if (NULL == pData) - return; + if( NULL == pData ) { + return; + } // Create faces ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ]; @@ -276,14 +277,22 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel, for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) { ObjFile::Face* const inp = pObjMesh->m_Faces[ index ]; + if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { pMesh->mNumFaces += inp->m_pVertices->size() - 1; + pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE; } else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { pMesh->mNumFaces += inp->m_pVertices->size(); - } - else { + pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT; + } else { ++pMesh->mNumFaces; + if (inp->m_pVertices->size() > 3) { + pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON; + } + else { + pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE; + } } } @@ -384,7 +393,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ]; // Copy all normals - if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) + if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size()) { const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex ); if ( normal >= pModel->m_Normals.size() ) @@ -394,21 +403,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, } // Copy all texture coordinates - if ( !pModel->m_TextureCoord.empty() ) + if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size()) { - if ( !pSourceFace->m_pTexturCoords->empty() ) - { - const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex ); - ai_assert( tex < pModel->m_TextureCoord.size() ); - for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) - { - if ( tex >= pModel->m_TextureCoord.size() ) - throw DeadlyImportError("OBJ: texture coord index out of range"); - - aiVector2D coord2d = pModel->m_TextureCoord[ tex ]; - pMesh->mTextureCoords[ i ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 ); - } - } + const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex ); + ai_assert( tex < pModel->m_TextureCoord.size() ); + + if ( tex >= pModel->m_TextureCoord.size() ) + throw DeadlyImportError("OBJ: texture coordinate index out of range"); + + const aiVector3D &coord3d = pModel->m_TextureCoord[ tex ]; + pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord3d.x, coord3d.y, coord3d.z ); } ai_assert( pMesh->mNumVertices > newIndex ); @@ -481,6 +485,15 @@ void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects } // ------------------------------------------------------------------------------------------------ +// Add clamp mode property to material if necessary +void ObjFileImporter::addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode) +{ + ai_assert( NULL != mat); + mat->AddProperty<int>(&clampMode, 1, AI_MATKEY_MAPPINGMODE_U(type, 0)); + mat->AddProperty<int>(&clampMode, 1, AI_MATKEY_MAPPINGMODE_V(type, 0)); +} + +// ------------------------------------------------------------------------------------------------ // Creates the material void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pScene ) { @@ -537,6 +550,7 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc mat->AddProperty( &pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT ); mat->AddProperty( &pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE ); mat->AddProperty( &pCurrentMaterial->specular, 1, AI_MATKEY_COLOR_SPECULAR ); + mat->AddProperty( &pCurrentMaterial->emissive, 1, AI_MATKEY_COLOR_EMISSIVE ); mat->AddProperty( &pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS ); mat->AddProperty( &pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY ); @@ -544,23 +558,80 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI ); // Adding textures - if ( 0 != pCurrentMaterial->texture.length ) + if ( 0 != pCurrentMaterial->texture.length ) + { mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureDiffuseType]) + { + addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE); + } + } if ( 0 != pCurrentMaterial->textureAmbient.length ) + { mat->AddProperty( &pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureAmbientType]) + { + addTextureMappingModeProperty(mat, aiTextureType_AMBIENT); + } + } + + if ( 0 != pCurrentMaterial->textureEmissive.length ) + mat->AddProperty( &pCurrentMaterial->textureEmissive, AI_MATKEY_TEXTURE_EMISSIVE(0)); if ( 0 != pCurrentMaterial->textureSpecular.length ) + { mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularType]) + { + addTextureMappingModeProperty(mat, aiTextureType_SPECULAR); + } + } if ( 0 != pCurrentMaterial->textureBump.length ) + { mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) + { + addTextureMappingModeProperty(mat, aiTextureType_HEIGHT); + } + } + + if ( 0 != pCurrentMaterial->textureNormal.length ) + { + mat->AddProperty( &pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) + { + addTextureMappingModeProperty(mat, aiTextureType_NORMALS); + } + } + + if ( 0 != pCurrentMaterial->textureDisp.length ) + { + mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) ); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureDispType]) + { + addTextureMappingModeProperty(mat, aiTextureType_DISPLACEMENT); + } + } if ( 0 != pCurrentMaterial->textureOpacity.length ) + { mat->AddProperty( &pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureOpacityType]) + { + addTextureMappingModeProperty(mat, aiTextureType_OPACITY); + } + } if ( 0 != pCurrentMaterial->textureSpecularity.length ) + { mat->AddProperty( &pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0)); + if (pCurrentMaterial->clamp[ObjFile::Material::TextureSpecularityType]) + { + addTextureMappingModeProperty(mat, aiTextureType_SHININESS); + } + } // Store material property info in material array in scene pScene->mMaterials[ pScene->mNumMaterials ] = mat; @@ -581,15 +652,12 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) // Assign parent to child pChild->mParent = pParent; - size_t sNumChildren = 0; - (void)sNumChildren; // remove warning on release build // If already children was assigned to the parent node, store them in a std::vector<aiNode*> temp; if (pParent->mChildren != NULL) { - sNumChildren = pParent->mNumChildren; - ai_assert( 0 != sNumChildren ); + ai_assert( 0 != pParent->mNumChildren ); for (size_t index = 0; index < pParent->mNumChildren; index++) { temp.push_back(pParent->mChildren [ index ] ); diff --git a/src/3rdparty/assimp/code/ObjFileImporter.h b/src/3rdparty/assimp/code/ObjFileImporter.h index ef8d5ecae..7799612a4 100644 --- a/src/3rdparty/assimp/code/ObjFileImporter.h +++ b/src/3rdparty/assimp/code/ObjFileImporter.h @@ -77,7 +77,7 @@ public: private: - //! \brief Appends the supported extention. + //! \brief Appends the supported extension. const aiImporterDesc* GetInfo () const; //! \brief File import implementation. @@ -87,7 +87,7 @@ private: void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene); //! \brief Creates all nodes stored in imported content. - aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData, unsigned int uiMeshIndex, + aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData, aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray); //! \brief Creates topology data like faces and meshes for the geometry. @@ -103,19 +103,17 @@ private: //! \brief Material creation. void createMaterials(const ObjFile::Model* pModel, aiScene* pScene); + void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1); - //! \brief Appends a child node to a parentnode and updates the datastructures. + //! \brief Appends a child node to a parent node and updates the data structures. void appendChildToParentNode(aiNode *pParent, aiNode *pChild); - //! \brief TODO! - void createAnimations(); - private: //! Data buffer std::vector<char> m_Buffer; //! Pointer to root object instance ObjFile::Object *m_pRootObject; - //! Absolute pathname of model in filesystem + //! Absolute pathname of model in file system std::string m_strAbsPath; }; diff --git a/src/3rdparty/assimp/code/ObjFileMtlImporter.cpp b/src/3rdparty/assimp/code/ObjFileMtlImporter.cpp index 0005086e4..7affd5139 100644 --- a/src/3rdparty/assimp/code/ObjFileMtlImporter.cpp +++ b/src/3rdparty/assimp/code/ObjFileMtlImporter.cpp @@ -49,6 +49,34 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { +// Material specific token +static const std::string DiffuseTexture = "map_kd"; +static const std::string AmbientTexture = "map_ka"; +static const std::string SpecularTexture = "map_ks"; +static const std::string OpacityTexture = "map_d"; +static const std::string BumpTexture1 = "map_bump"; +static const std::string BumpTexture2 = "map_Bump"; +static const std::string BumpTexture3 = "bump"; +static const std::string NormalTexture = "map_Kn"; +static const std::string DisplacementTexture = "disp"; +static const std::string SpecularityTexture = "map_ns"; + +// texture option specific token +static const std::string BlendUOption = "-blendu"; +static const std::string BlendVOption = "-blendv"; +static const std::string BoostOption = "-boost"; +static const std::string ModifyMapOption = "-mm"; +static const std::string OffsetOption = "-o"; +static const std::string ScaleOption = "-s"; +static const std::string TurbulenceOption = "-t"; +static const std::string ResolutionOption = "-texres"; +static const std::string ClampOption = "-clamp"; +static const std::string BumpOption = "-bm"; +static const std::string ChannelOption = "-imfchan"; +static const std::string TypeOption = "-type"; + + + // ------------------------------------------------------------------- // Constructor ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer, @@ -118,6 +146,11 @@ void ObjFileMtlImporter::load() ++m_DataIt; getColorRGBA( &m_pModel->m_pCurrentMaterial->specular ); } + else if (*m_DataIt == 'e') + { + ++m_DataIt; + getColorRGBA( &m_pModel->m_pCurrentMaterial->emissive ); + } m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); } break; @@ -249,51 +282,134 @@ void ObjFileMtlImporter::createMaterial() // ------------------------------------------------------------------- // Gets a texture name from data. -void ObjFileMtlImporter::getTexture() -{ - aiString *out = NULL; - - // FIXME: just a quick'n'dirty hack, consider cleanup later +void ObjFileMtlImporter::getTexture() { + aiString *out( NULL ); + int clampIndex = -1; - // Diffuse texture - if (!ASSIMP_strincmp(&(*m_DataIt),"map_kd",6)) + const char *pPtr( &(*m_DataIt) ); + if ( !ASSIMP_strincmp( pPtr, DiffuseTexture.c_str(), DiffuseTexture.size() ) ) { + // Diffuse texture out = & m_pModel->m_pCurrentMaterial->texture; - - // Ambient texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ka",6)) + clampIndex = ObjFile::Material::TextureDiffuseType; + } else if ( !ASSIMP_strincmp( pPtr,AmbientTexture.c_str(),AmbientTexture.size() ) ) { + // Ambient texture out = & m_pModel->m_pCurrentMaterial->textureAmbient; - - // Specular texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ks",6)) + clampIndex = ObjFile::Material::TextureAmbientType; + } else if (!ASSIMP_strincmp( pPtr, SpecularTexture.c_str(), SpecularTexture.size())) { + // Specular texture out = & m_pModel->m_pCurrentMaterial->textureSpecular; - - // Opacity texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_d",5)) + clampIndex = ObjFile::Material::TextureSpecularType; + } else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), OpacityTexture.size() ) ) { + // Opacity texture out = & m_pModel->m_pCurrentMaterial->textureOpacity; - - // Ambient texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ka",6)) + clampIndex = ObjFile::Material::TextureOpacityType; + } else if (!ASSIMP_strincmp( pPtr,"map_ka",6)) { + // Ambient texture out = & m_pModel->m_pCurrentMaterial->textureAmbient; - - // Bump texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_bump",8) || !ASSIMP_strincmp(&(*m_DataIt),"bump",4)) + clampIndex = ObjFile::Material::TextureAmbientType; + } else if (!ASSIMP_strincmp(&(*m_DataIt),"map_emissive",6)) { + // Emissive texture + out = & m_pModel->m_pCurrentMaterial->textureEmissive; + clampIndex = ObjFile::Material::TextureEmissiveType; + } else if ( !ASSIMP_strincmp( pPtr, BumpTexture1.c_str(), BumpTexture1.size() ) || + !ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), BumpTexture2.size() ) || + !ASSIMP_strincmp( pPtr, BumpTexture3.c_str(), BumpTexture3.size() ) ) { + // Bump texture out = & m_pModel->m_pCurrentMaterial->textureBump; - - // Specularity scaling (glossiness) - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ns",6)) + clampIndex = ObjFile::Material::TextureBumpType; + } else if (!ASSIMP_strincmp( pPtr,NormalTexture.c_str(), NormalTexture.size())) { + // Normal map + out = & m_pModel->m_pCurrentMaterial->textureNormal; + clampIndex = ObjFile::Material::TextureNormalType; + } else if (!ASSIMP_strincmp( pPtr, DisplacementTexture.c_str(), DisplacementTexture.size() ) ) { + // Displacement texture + out = &m_pModel->m_pCurrentMaterial->textureDisp; + clampIndex = ObjFile::Material::TextureDispType; + } else if (!ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(),SpecularityTexture.size() ) ) { + // Specularity scaling (glossiness) out = & m_pModel->m_pCurrentMaterial->textureSpecularity; - - else - { + clampIndex = ObjFile::Material::TextureSpecularityType; + } else { DefaultLogger::get()->error("OBJ/MTL: Encountered unknown texture type"); return; } + bool clamp = false; + getTextureOption(clamp); + m_pModel->m_pCurrentMaterial->clamp[clampIndex] = clamp; + std::string strTexture; m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strTexture ); out->Set( strTexture ); } +/* ///////////////////////////////////////////////////////////////////////////// + * Texture Option + * ///////////////////////////////////////////////////////////////////////////// + * According to http://en.wikipedia.org/wiki/Wavefront_.obj_file#Texture_options + * Texture map statement can contains various texture option, for example: + * + * map_Ka -o 1 1 1 some.png + * map_Kd -clamp on some.png + * + * So we need to parse and skip these options, and leave the last part which is + * the url of image, otherwise we will get a wrong url like "-clamp on some.png". + * + * Because aiMaterial supports clamp option, so we also want to return it + * ///////////////////////////////////////////////////////////////////////////// + */ +void ObjFileMtlImporter::getTextureOption(bool &clamp) +{ + m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); + + //If there is any more texture option + while (!isEndOfBuffer(m_DataIt, m_DataItEnd) && *m_DataIt == '-') + { + const char *pPtr( &(*m_DataIt) ); + //skip option key and value + int skipToken = 1; + + if (!ASSIMP_strincmp(pPtr, ClampOption.c_str(), ClampOption.size())) + { + DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); + char value[3]; + CopyNextWord(it, m_DataItEnd, value, sizeof(value) / sizeof(*value)); + if (!ASSIMP_strincmp(value, "on", 2)) + { + clamp = true; + } + + skipToken = 2; + } + else if ( !ASSIMP_strincmp(pPtr, BlendUOption.c_str(), BlendUOption.size()) + || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), BlendVOption.size()) + || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), BoostOption.size()) + || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), ResolutionOption.size()) + || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), BumpOption.size()) + || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), ChannelOption.size()) + || !ASSIMP_strincmp(pPtr, TypeOption.c_str(), TypeOption.size()) ) + { + skipToken = 2; + } + else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), ModifyMapOption.size())) + { + skipToken = 3; + } + else if ( !ASSIMP_strincmp(pPtr, OffsetOption.c_str(), OffsetOption.size()) + || !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), ScaleOption.size()) + || !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), TurbulenceOption.size()) + ) + { + skipToken = 4; + } + + for (int i = 0; i < skipToken; ++i) + { + m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); + } + } +} + // ------------------------------------------------------------------- } // Namespace Assimp diff --git a/src/3rdparty/assimp/code/ObjFileMtlImporter.h b/src/3rdparty/assimp/code/ObjFileMtlImporter.h index 7fdd0b1b8..207c56063 100644 --- a/src/3rdparty/assimp/code/ObjFileMtlImporter.h +++ b/src/3rdparty/assimp/code/ObjFileMtlImporter.h @@ -92,6 +92,7 @@ private: void createMaterial(); /// Get texture name from loaded data. void getTexture(); + void getTextureOption(bool &clamp); private: //! Absolute pathname diff --git a/src/3rdparty/assimp/code/ObjFileParser.cpp b/src/3rdparty/assimp/code/ObjFileParser.cpp index 4486bb0a8..4ffd86a9b 100644 --- a/src/3rdparty/assimp/code/ObjFileParser.cpp +++ b/src/3rdparty/assimp/code/ObjFileParser.cpp @@ -50,10 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../include/assimp/types.h" #include "DefaultIOSystem.h" -namespace Assimp -{ +namespace Assimp { -// ------------------------------------------------------------------- const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME; // ------------------------------------------------------------------- @@ -71,9 +69,10 @@ ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModel m_pModel = new ObjFile::Model(); m_pModel->m_ModelName = strModelName; + // create default material and store it m_pModel->m_pDefaultMaterial = new ObjFile::Material(); m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL ); - m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL ); + m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL ); m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial; // Start parsing the file @@ -84,9 +83,6 @@ ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModel // Destructor ObjFileParser::~ObjFileParser() { - /*delete m_pModel->m_pDefaultMaterial; - m_pModel->m_pDefaultMaterial = NULL;*/ - delete m_pModel; m_pModel = NULL; } @@ -112,19 +108,14 @@ void ObjFileParser::parseFile() case 'v': // Parse a vertex texture coordinate { ++m_DataIt; - if (*m_DataIt == ' ') - { - // Read in vertex definition + if (*m_DataIt == ' ' || *m_DataIt == '\t') { + // read in vertex definition getVector3(m_pModel->m_Vertices); - } - else if (*m_DataIt == 't') - { - // Read in texture coordinate (2D) - ++m_DataIt; - getVector2(m_pModel->m_TextureCoord); - } - else if (*m_DataIt == 'n') - { + } else if (*m_DataIt == 't') { + // read in texture coordinate ( 2D or 3D ) + ++m_DataIt; + getVector( m_pModel->m_TextureCoord ); + } else if (*m_DataIt == 'n') { // Read in normal vector definition ++m_DataIt; getVector3( m_pModel->m_Normals ); @@ -153,9 +144,12 @@ void ObjFileParser::parseFile() } break; - case 'm': // Parse a material library + case 'm': // Parse a material library or merging group ('mg') { - getMaterialLib(); + if (*(m_DataIt + 1) == 'g') + getGroupNumberAndResolution(); + else + getMaterialLib(); } break; @@ -200,6 +194,8 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) break; ++m_DataIt; } + + ai_assert(index < length); pBuffer[index] = '\0'; } @@ -207,23 +203,70 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) // Copy the next line into a temporary buffer void ObjFileParser::copyNextLine(char *pBuffer, size_t length) { - size_t index = 0; - while (m_DataIt != m_DataItEnd) + size_t index = 0u; + + // some OBJ files have line continuations using \ (such as in C++ et al) + bool continuation = false; + for (;m_DataIt != m_DataItEnd && index < length-1; ++m_DataIt) { - if (*m_DataIt == '\n' || *m_DataIt == '\r' || index == length-1) + const char c = *m_DataIt; + if (c == '\\') { + continuation = true; + continue; + } + + if (c == '\n' || c == '\r') { + if(continuation) { + pBuffer[ index++ ] = ' '; + continue; + } break; + } - pBuffer[ index ] = *m_DataIt; - ++index; - ++m_DataIt; + continuation = false; + pBuffer[ index++ ] = c; } + ai_assert(index < length); pBuffer[ index ] = '\0'; } // ------------------------------------------------------------------- +void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) { + size_t numComponents( 0 ); + DataArrayIt tmp( m_DataIt ); + while( !IsLineEnd( *tmp ) ) { + if( *tmp == ' ' ) { + ++numComponents; + } + tmp++; + } + float x, y, z; + if( 2 == numComponents ) { + copyNextWord( m_buffer, BUFFERSIZE ); + x = ( float ) fast_atof( m_buffer ); + + copyNextWord( m_buffer, BUFFERSIZE ); + y = ( float ) fast_atof( m_buffer ); + z = 0.0; + } else if( 3 == numComponents ) { + copyNextWord( m_buffer, BUFFERSIZE ); + x = ( float ) fast_atof( m_buffer ); + + copyNextWord( m_buffer, BUFFERSIZE ); + y = ( float ) fast_atof( m_buffer ); + + copyNextWord( m_buffer, BUFFERSIZE ); + z = ( float ) fast_atof( m_buffer ); + } else { + ai_assert( !"Invalid number of components" ); + } + point3d_array.push_back( aiVector3D( x, y, z ) ); + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); +} + +// ------------------------------------------------------------------- // Get values for a new 3D vector instance -void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array) -{ +void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array) { float x, y, z; copyNextWord(m_buffer, BUFFERSIZE); x = (float) fast_atof(m_buffer); @@ -231,18 +274,16 @@ void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array) copyNextWord(m_buffer, BUFFERSIZE); y = (float) fast_atof(m_buffer); - copyNextWord(m_buffer, BUFFERSIZE); - z = (float) fast_atof(m_buffer); + copyNextWord( m_buffer, BUFFERSIZE ); + z = ( float ) fast_atof( m_buffer ); point3d_array.push_back( aiVector3D( x, y, z ) ); - //skipLine(); m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get values for a new 2D vector instance -void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) -{ +void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) { float x, y; copyNextWord(m_buffer, BUFFERSIZE); x = (float) fast_atof(m_buffer); @@ -274,6 +315,10 @@ void ObjFileParser::getFace(aiPrimitiveType type) std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>; bool hasNormal = false; + const int vSize = m_pModel->m_Vertices.size(); + const int vtSize = m_pModel->m_TextureCoord.size(); + const int vnSize = m_pModel->m_Normals.size(); + const bool vt = (!m_pModel->m_TextureCoord.empty()); const bool vn = (!m_pModel->m_Normals.empty()); int iStep = 0, iPos = 0; @@ -307,7 +352,11 @@ void ObjFileParser::getFace(aiPrimitiveType type) { //OBJ USES 1 Base ARRAYS!!!! const int iVal = atoi( pPtr ); + + // increment iStep position based off of the sign and # of digits int tmp = iVal; + if (iVal < 0) + ++iStep; while ( ( tmp = tmp / 10 )!=0 ) ++iStep; @@ -332,6 +381,27 @@ void ObjFileParser::getFace(aiPrimitiveType type) reportErrorTokenInFace(); } } + else if ( iVal < 0 ) + { + // Store relatively index + if ( 0 == iPos ) + { + pIndices->push_back( vSize + iVal ); + } + else if ( 1 == iPos ) + { + pTexID->push_back( vtSize + iVal ); + } + else if ( 2 == iPos ) + { + pNormalID->push_back( vnSize + iVal ); + hasNormal = true; + } + else + { + reportErrorTokenInFace(); + } + } } pPtr += iStep; } @@ -528,18 +598,12 @@ int ObjFileParser::getMaterialIndex( const std::string &strMaterialName ) // Getter for a group name. void ObjFileParser::getGroupName() { - // Get next word from data buffer - m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd); - m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd); + std::string strGroupName; + + m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName); if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) return; - // Store the group name in the group library - char *pStart = &(*m_DataIt); - while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) ) - m_DataIt++; - std::string strGroupName( pStart, &(*m_DataIt) ); - // Change active group, if necessary if ( m_pModel->m_strActiveGroup != strGroupName ) { @@ -575,6 +639,15 @@ void ObjFileParser::getGroupNumber() } // ------------------------------------------------------------------- +// Not supported +void ObjFileParser::getGroupNumberAndResolution() +{ + // Not used + + m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine ); +} + +// ------------------------------------------------------------------- // Stores values for a new object instance, name will be used to // identify it. void ObjFileParser::getObjectName() diff --git a/src/3rdparty/assimp/code/ObjFileParser.h b/src/3rdparty/assimp/code/ObjFileParser.h index ed374364a..f6473a11e 100644 --- a/src/3rdparty/assimp/code/ObjFileParser.h +++ b/src/3rdparty/assimp/code/ObjFileParser.h @@ -37,8 +37,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ - - #ifndef OBJ_FILEPARSER_H_INC #define OBJ_FILEPARSER_H_INC @@ -79,29 +77,34 @@ public: ObjFile::Model *GetModel() const; private: - /// Parse the loadedfile + /// Parse the loaded file void parseFile(); /// Method to copy the new delimited word in the current line. void copyNextWord(char *pBuffer, size_t length); /// Method to copy the new line. void copyNextLine(char *pBuffer, size_t length); - /// Stores the following 3d vector. + /// Stores the vector + void getVector( std::vector<aiVector3D> &point3d_array ); + /// Stores the following 3d vector. void getVector3( std::vector<aiVector3D> &point3d_array ); /// Stores the following 3d vector. void getVector2(std::vector<aiVector2D> &point2d_array); - /// Stores the following face. + /// Stores the following face. void getFace(aiPrimitiveType type); - void getMaterialDesc(); + /// Reads the material description. + void getMaterialDesc(); /// Gets a comment. void getComment(); /// Gets a a material library. void getMaterialLib(); /// Creates a new material. void getNewMaterial(); - /// Gets the groupname from file. + /// Gets the group name from file. void getGroupName(); /// Gets the group number from file. void getGroupNumber(); + /// Gets the group number and resolution from file. + void getGroupNumberAndResolution(); /// Returns the index of the material. Is -1 if not material was found. int getMaterialIndex( const std::string &strMaterialName ); /// Parse object name diff --git a/src/3rdparty/assimp/code/ObjTools.h b/src/3rdparty/assimp/code/ObjTools.h index 849b20b68..30c59db4c 100644 --- a/src/3rdparty/assimp/code/ObjTools.h +++ b/src/3rdparty/assimp/code/ObjTools.h @@ -107,7 +107,7 @@ inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd ) return pBuffer; } -/** @brief Returns ponter a next token +/** @brief Returns pointer a next token * @param pBuffer Pointer to data buffer * @param pEnd Pointer to end of buffer * @return Pointer to next token @@ -157,7 +157,6 @@ template<class char_t> inline char_t getName( char_t it, char_t end, std::string &name ) { name = ""; - it = getNextToken<char_t>( it, end ); if ( isEndOfBuffer( it, end ) ) return end; @@ -172,6 +171,10 @@ inline char_t getName( char_t it, char_t end, std::string &name ) ++it; // Get name + // if there is no name, and the previous char is a separator, come back to start + while (&(*it) < pStart) { + ++it; + } std::string strName( pStart, &(*it) ); if ( strName.empty() ) return it; diff --git a/src/3rdparty/assimp/code/OgreImporter.cpp b/src/3rdparty/assimp/code/OgreImporter.cpp index fcb4114ad..94c7701ba 100644 --- a/src/3rdparty/assimp/code/OgreImporter.cpp +++ b/src/3rdparty/assimp/code/OgreImporter.cpp @@ -38,17 +38,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -/** @file OgreImporter.cpp - * @brief Implementation of the Ogre XML (.mesh.xml) loader. - */ #include "AssimpPCH.h" + #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER #include <vector> #include <sstream> -using namespace std; -#include "OgreImporter.hpp" +#include "OgreImporter.h" #include "TinyFormatter.h" #include "irrXMLWrapper.h" @@ -65,190 +62,198 @@ static const aiImporterDesc desc = { "mesh.xml" }; +using namespace std; + namespace Assimp { namespace Ogre { +const aiImporterDesc* OgreImporter::GetInfo() const +{ + return &desc; +} + +void OgreImporter::SetupProperties(const Importer* pImp) +{ + m_userDefinedMaterialLibFile = pImp->GetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "Scene.material"); + m_detectTextureTypeFromFilename = pImp->GetPropertyBool(AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME, false); +} bool OgreImporter::CanRead(const std::string &pFile, Assimp::IOSystem *pIOHandler, bool checkSig) const { - if(!checkSig)//Check File Extension - { - std::string extension("mesh.xml"); - int l=extension.length(); - return pFile.substr(pFile.length()-l, l)==extension; + if (!checkSig) { + return EndsWith(pFile, ".mesh.xml", false); } - else//Check file Header - { - const char* tokens[] = {"<mesh>"}; - return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1); - } -} + const char* tokens[] = { "<mesh>" }; + return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1); +} void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Assimp::IOSystem *pIOHandler) { - m_CurrentFilename=pFile; - m_CurrentIOHandler=pIOHandler; - m_CurrentScene=pScene; - - //Open the File: + // -------------------- Initial file and XML operations -------------------- + + // Open boost::scoped_ptr<IOStream> file(pIOHandler->Open(pFile)); - if( file.get() == NULL) - throw DeadlyImportError("Failed to open file "+pFile+"."); + if (!file.get()) { + throw DeadlyImportError("Failed to open file " + pFile); + } - //Read the Mesh File: - boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get())); - XmlReader* MeshFile = irr::io::createIrrXMLReader(mIOWrapper.get()); - if(!MeshFile)//parse the xml file - throw DeadlyImportError("Failed to create XML Reader for "+pFile); + // Read + boost::scoped_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(file.get())); + boost::scoped_ptr<XmlReader> reader(irr::io::createIrrXMLReader(xmlStream.get())); + if (!reader) { + throw DeadlyImportError("Failed to create XML Reader for " + pFile); + } + DefaultLogger::get()->debug("Opened a XML reader for " + pFile); - DefaultLogger::get()->debug("Mesh File opened"); - - //Read root Node: - if(!(XmlRead(MeshFile) && string(MeshFile->getNodeName())=="mesh")) - { - throw DeadlyImportError("Root Node is not <mesh>! "+pFile+" "+MeshFile->getNodeName()); + // Read root node + NextNode(reader.get()); + if (!CurrentNodeNameEquals(reader.get(), "mesh")) { + throw DeadlyImportError("Root node is not <mesh> but <" + string(reader->getNodeName()) + "> in " + pFile); } - - //eventually load shared geometry - XmlRead(MeshFile);//shared geometry is optional, so we need a reed for the next two if's - if(MeshFile->getNodeName()==string("sharedgeometry")) + + // Node names + const string nnSharedGeometry = "sharedgeometry"; + const string nnVertexBuffer = "vertexbuffer"; + const string nnSubMeshes = "submeshes"; + const string nnSubMesh = "submesh"; + const string nnSubMeshNames = "submeshnames"; + const string nnSkeletonLink = "skeletonlink"; + + // -------------------- Shared Geometry -------------------- + // This can be used to share geometry between submeshes + + NextNode(reader.get()); + if (CurrentNodeNameEquals(reader.get(), nnSharedGeometry)) { - unsigned int NumVertices=GetAttribute<int>(MeshFile, "vertexcount");; + DefaultLogger::get()->debug("Reading shared geometry"); + unsigned int NumVertices = GetAttribute<unsigned int>(reader.get(), "vertexcount"); - XmlRead(MeshFile); - while(MeshFile->getNodeName()==string("vertexbuffer")) - { - ReadVertexBuffer(m_SharedGeometry, MeshFile, NumVertices); + NextNode(reader.get()); + while(CurrentNodeNameEquals(reader.get(), nnVertexBuffer)) { + ReadVertexBuffer(m_SharedGeometry, reader.get(), NumVertices); } } - //Go to the submeshs: - if(MeshFile->getNodeName()!=string("submeshes")) - { - throw DeadlyImportError("No <submeshes> node in <mesh> node! "+pFile); + // -------------------- Sub Meshes -------------------- + + if (!CurrentNodeNameEquals(reader.get(), nnSubMeshes)) { + throw DeadlyImportError("Could not find <submeshes> node inside root <mesh> node"); } + vector<boost::shared_ptr<SubMesh> > subMeshes; + vector<aiMaterial*> materials; - //-------------------Read the submeshs and materials:----------------------- - std::list<boost::shared_ptr<SubMesh> > SubMeshes; - vector<aiMaterial*> Materials; - XmlRead(MeshFile); - while(MeshFile->getNodeName()==string("submesh")) + NextNode(reader.get()); + while(CurrentNodeNameEquals(reader.get(), nnSubMesh)) { - SubMesh* theSubMesh=new SubMesh(); - theSubMesh->MaterialName=GetAttribute<string>(MeshFile, "material"); - DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh->MaterialName); - ReadSubMesh(*theSubMesh, MeshFile); + SubMesh* submesh = new SubMesh(); + ReadSubMesh(subMeshes.size(), *submesh, reader.get()); + + // Just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n; + // so it is important to do this before pushing the mesh in the vector! + /// @todo Not sure if this really is needed, refactor out if possible. + submesh->MaterialIndex = subMeshes.size(); - //just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n; - //so it is important to do this before pushing the mesh in the vector! - theSubMesh->MaterialIndex=SubMeshes.size(); + subMeshes.push_back(boost::shared_ptr<SubMesh>(submesh)); - SubMeshes.push_back(boost::shared_ptr<SubMesh>(theSubMesh)); + /** @todo What is the correct way of handling empty ref here. + Does Assimp require there to be a valid material index for each mesh, + even if its a dummy material. */ + aiMaterial* material = ReadMaterial(pFile, pIOHandler, submesh->MaterialName); + materials.push_back(material); + } - //Load the Material: - aiMaterial* MeshMat=LoadMaterial(theSubMesh->MaterialName); - - //Set the Material: - Materials.push_back(MeshMat); + if (subMeshes.empty()) { + throw DeadlyImportError("Could not find <submeshes> node inside root <mesh> node"); } - if(SubMeshes.empty()) - throw DeadlyImportError("no submesh loaded!"); - if(SubMeshes.size()!=Materials.size()) - throw DeadlyImportError("materialcount doesn't match mesh count!"); + // This is really a internal error if we failed to create dummy materials. + if (subMeshes.size() != materials.size()) { + throw DeadlyImportError("Internal Error: Material count does not match the submesh count"); + } - //____________________________________________________________ + // Skip submesh names. + /// @todo Should these be read to scene etc. metadata? + if (CurrentNodeNameEquals(reader.get(), nnSubMeshNames)) + { + NextNode(reader.get()); + while(CurrentNodeNameEquals(reader.get(), nnSubMesh)) { + NextNode(reader.get()); + } + } + // -------------------- Skeleton -------------------- - //----------------Load the skeleton: ------------------------------- vector<Bone> Bones; vector<Animation> Animations; - if(MeshFile->getNodeName()==string("skeletonlink")) + + if (CurrentNodeNameEquals(reader.get(), nnSkeletonLink)) { - string SkeletonFile=GetAttribute<string>(MeshFile, "name"); - LoadSkeleton(SkeletonFile, Bones, Animations); - XmlRead(MeshFile); + string skeletonFile = GetAttribute<string>(reader.get(), "name"); + if (!skeletonFile.empty()) + { + ReadSkeleton(pFile, pIOHandler, pScene, skeletonFile, Bones, Animations); + } + else + { + DefaultLogger::get()->debug("Found a unusual <" + nnSkeletonLink + "> with a empty file reference"); + } + NextNode(reader.get()); } else { - DefaultLogger::get()->warn("No skeleton file will be loaded"); - DefaultLogger::get()->warn(MeshFile->getNodeName()); + DefaultLogger::get()->debug("Mesh has no assigned skeleton with <" + nnSkeletonLink + ">"); } - //__________________________________________________________________ - - //now there might be boneassignments for the shared geometry: - if(MeshFile->getNodeName()==string("boneassignments")) - { - ReadBoneWeights(m_SharedGeometry, MeshFile); + // Now there might be <boneassignments> for the shared geometry + if (CurrentNodeNameEquals(reader.get(), "boneassignments")) { + ReadBoneWeights(m_SharedGeometry, reader.get()); } - - //----------------- Process Meshs ----------------------- - BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes) + // -------------------- Process Results -------------------- + BOOST_FOREACH(boost::shared_ptr<SubMesh> submesh, subMeshes) { - ProcessSubMesh(*theSubMesh, m_SharedGeometry); + ProcessSubMesh(*submesh.get(), m_SharedGeometry); } - //_______________________________________________________ + // -------------------- Apply to aiScene -------------------- + // Materials + pScene->mMaterials = new aiMaterial*[materials.size()]; + pScene->mNumMaterials = materials.size(); - - //----------------- Now fill the Assimp scene --------------------------- - - //put the aiMaterials in the scene: - m_CurrentScene->mMaterials=new aiMaterial*[Materials.size()]; - m_CurrentScene->mNumMaterials=Materials.size(); - for(unsigned int i=0; i<Materials.size(); ++i) - m_CurrentScene->mMaterials[i]=Materials[i]; - - //create the aiMehs... - vector<aiMesh*> aiMeshes; - BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, SubMeshes) - { - aiMeshes.push_back(CreateAssimpSubMesh(*theSubMesh, Bones)); + for(size_t i=0, len=materials.size(); i<len; ++i) { + pScene->mMaterials[i] = materials[i]; } - //... and put them in the scene: - m_CurrentScene->mNumMeshes=aiMeshes.size(); - m_CurrentScene->mMeshes=new aiMesh*[aiMeshes.size()]; - memcpy(m_CurrentScene->mMeshes, &(aiMeshes[0]), sizeof(aiMeshes[0])*aiMeshes.size()); - //Create the root node - m_CurrentScene->mRootNode=new aiNode("root"); + // Meshes + pScene->mMeshes = new aiMesh*[subMeshes.size()]; + pScene->mNumMeshes = subMeshes.size(); - //link the meshs with the root node: - m_CurrentScene->mRootNode->mMeshes=new unsigned int[SubMeshes.size()]; - m_CurrentScene->mRootNode->mNumMeshes=SubMeshes.size(); - for(unsigned int i=0; i<SubMeshes.size(); ++i) - m_CurrentScene->mRootNode->mMeshes[i]=i; + for(size_t i=0, len=subMeshes.size(); i<len; ++i) + { + boost::shared_ptr<SubMesh> submesh = subMeshes[i]; + pScene->mMeshes[i] = CreateAssimpSubMesh(pScene, *(submesh.get()), Bones); + } + // Create the root node + pScene->mRootNode = new aiNode(); + pScene->mRootNode->mMeshes = new unsigned int[subMeshes.size()]; + pScene->mRootNode->mNumMeshes = subMeshes.size(); + for(size_t i=0, len=subMeshes.size(); i<len; ++i) { + pScene->mRootNode->mMeshes[i] = static_cast<unsigned int>(i); + } - CreateAssimpSkeleton(Bones, Animations); - PutAnimationsInScene(Bones, Animations); - //___________________________________________________________ -} - - -const aiImporterDesc* OgreImporter::GetInfo () const -{ - return &desc; -} - - -void OgreImporter::SetupProperties(const Importer* pImp) -{ - m_MaterialLibFilename=pImp->GetPropertyString(AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE, "Scene.material"); - m_TextureTypeFromFilename=pImp->GetPropertyBool(AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME, false); + // Skeleton and animations + CreateAssimpSkeleton(pScene, Bones, Animations); } +} // Ogre +} // Assimp -}//namespace Ogre -}//namespace Assimp - -#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER +#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER diff --git a/src/3rdparty/assimp/code/OgreImporter.h b/src/3rdparty/assimp/code/OgreImporter.h new file mode 100644 index 000000000..f43398751 --- /dev/null +++ b/src/3rdparty/assimp/code/OgreImporter.h @@ -0,0 +1,230 @@ + +#ifndef AI_OGREIMPORTER_H_INC +#define AI_OGREIMPORTER_H_INC + +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER + +#include "BaseImporter.h" +#include "OgreParsingUtils.h" + +namespace Assimp +{ +namespace Ogre +{ + +struct Face; +struct BoneWeight; +struct Bone; +struct Animation; + +/// Ogre SubMesh +struct SubMesh +{ + bool UseSharedGeometry; + bool Use32bitIndexes; + + std::string Name; + std::string MaterialName; + + bool HasGeometry; + bool HasPositions; + bool HasNormals; + bool HasTangents; + + std::vector<Face> Faces; + std::vector<aiVector3D> Positions; + std::vector<aiVector3D> Normals; + std::vector<aiVector3D> Tangents; + + /// Arbitrary number of texcoords, they are nearly always 2d, but Assimp has always 3d texcoords, n vectors(outer) with texcoords for each vertex(inner). + std::vector<std::vector<aiVector3D> > Uvs; + + /// A list(inner) of bones for each vertex(outer). + std::vector<std::vector<BoneWeight> > Weights; + + /// The Index in the Assimp material array from the material witch is attached to this submesh. + int MaterialIndex; + + // The highest index of a bone from a bone weight, this is needed to create the Assimp bone struct. Converting from vertex-bones to bone-vertices. + unsigned int BonesUsed; + + SubMesh() : + UseSharedGeometry(false), + Use32bitIndexes(false), + HasGeometry(false), + HasPositions(false), + HasNormals(false), + HasTangents(false), + MaterialIndex(-1), + BonesUsed(0) + { + } +}; + +/** Importer for Ogre mesh, skeleton and material formats. + @todo Support vertex colors + @todo Support multiple TexCoords (this is already done??) */ +class OgreImporter : public BaseImporter +{ +public: + /// BaseImporter override. + virtual bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const; + + /// BaseImporter override. + virtual void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); + + /// BaseImporter override. + virtual const aiImporterDesc *GetInfo() const; + + /// BaseImporter override. + virtual void SetupProperties(const Importer *pImp); + +private: + //-------------------------------- OgreMesh.cpp ------------------------------- + + /// Helper Functions to read parts of the XML File. + void ReadSubMesh(const unsigned int submeshIndex, SubMesh &submesh, XmlReader *reader); + + /// Reads a single Vertexbuffer and writes its data in the Submesh. + static void ReadVertexBuffer(SubMesh &submesh, XmlReader *reader, const unsigned int numVertices); + + /// Reads bone weights are stores them into the given submesh. + static void ReadBoneWeights(SubMesh &submesh, XmlReader *reader); + + /// After Loading a SubMehs some work needs to be done (make all Vertexes unique, normalize weights). + static void ProcessSubMesh(SubMesh &submesh, SubMesh &sharedGeometry); + + /// Uses the bone data to convert a SubMesh into a aiMesh which will be created and returned. + aiMesh *CreateAssimpSubMesh(aiScene *pScene, const SubMesh &submesh, const std::vector<Bone> &bones) const; + + //-------------------------------- OgreSkeleton.cpp ------------------------------- + + /// Writes the results in Bones and Animations, Filename is not const, because its call-by-value and the function will change it! + void ReadSkeleton(const std::string &pFile, Assimp::IOSystem *pIOHandler, const aiScene *pScene, + const std::string &skeletonFile, std::vector<Bone> &Bones, std::vector<Animation> &Animations) const; + + /// Converts the animations in aiAnimations and puts them into the scene. + void PutAnimationsInScene(aiScene *pScene, const std::vector<Bone> &Bones, const std::vector<Animation> &Animations); + + /// Creates the aiSkeleton in current scene. + void CreateAssimpSkeleton(aiScene *pScene, const std::vector<Bone> &bones, const std::vector<Animation> &animations); + + /// Recursively creates a filled aiNode from a given root bone. + static aiNode* CreateNodeFromBone(int boneId, const std::vector<Bone> &bones, aiNode *parent); + + //-------------------------------- OgreMaterial.cpp ------------------------------- + + /// Reads material + aiMaterial* ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string MaterialName); + + // These functions parse blocks from a material file from @c ss. Starting parsing from "{" and ending it to "}". + bool ReadTechnique(const std::string &techniqueName, std::stringstream &ss, aiMaterial *material); + bool ReadPass(const std::string &passName, std::stringstream &ss, aiMaterial *material); + bool ReadTextureUnit(const std::string &textureUnitName, std::stringstream &ss, aiMaterial *material); + + std::string m_userDefinedMaterialLibFile; + bool m_detectTextureTypeFromFilename; + + /// VertexBuffer for the sub meshes that use shader geometry. + SubMesh m_SharedGeometry; + + std::map<aiTextureType, unsigned int> m_textures; +}; + +/// Simplified face. +/** @todo Support other polygon types than just just triangles. Move to using aiFace. */ +struct Face +{ + unsigned int VertexIndices[3]; +}; + +/// Ogre Bone assignment +struct BoneAssignment +{ + /// Bone ID from Ogre. + unsigned int BoneId; + // Bone name for Assimp. + std::string BoneName; +}; + +/// Ogre Bone weight +struct BoneWeight +{ + /// Bone Id + unsigned int Id; + /// BoneWeight + float Value; +}; + + +/// Ogre Bone +struct Bone +{ + std::string Name; + + int Id; + int ParentId; + + aiVector3D Position; + aiVector3D RotationAxis; + float RotationAngle; + + aiMatrix4x4 BoneToWorldSpace; + + std::vector<int> Children; + + Bone() : + Id(-1), + ParentId(-1), + RotationAngle(0.0f) + { + } + + /// Returns if this bone is parented. + bool IsParented() const { return (ParentId != -1); } + + /// This operator is needed to sort the bones by Id in a vector<Bone>. + bool operator<(const Bone &other) const { return (Id < other.Id); } + + /// This operator is needed to find a bone by its name in a vector<Bone> + bool operator==(const std::string& other) const { return Name == other; } + bool operator==(const aiString& other) const { return Name == std::string(other.data); } + + /// @note Implemented in OgreSkeleton.cpp + void CalculateBoneToWorldSpaceMatrix(std::vector<Bone>& Bones); +}; + +/// Ogre animation key frame +/** Transformations for a frame. */ +struct KeyFrame +{ + float Time; + aiVector3D Position; + aiQuaternion Rotation; + aiVector3D Scaling; +}; + +/// Ogre animation track +/** Keyframes for one bone. */ +struct Track +{ + std::string BoneName; + std::vector<KeyFrame> Keyframes; +}; + +/// Ogre animation +struct Animation +{ + /// Name + std::string Name; + /// Length + float Length; + /// Tracks + std::vector<Track> Tracks; +}; + +} // Ogre +} // Assimp + +#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER +#endif // AI_OGREIMPORTER_H_INC diff --git a/src/3rdparty/assimp/code/OgreMaterial.cpp b/src/3rdparty/assimp/code/OgreMaterial.cpp index 1276227e7..157af24aa 100644 --- a/src/3rdparty/assimp/code/OgreMaterial.cpp +++ b/src/3rdparty/assimp/code/OgreMaterial.cpp @@ -38,59 +38,36 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -/** -This file contains material related code. This is -spilitted up from the main file OgreImporter.cpp -to make it shorter easier to maintain. -*/ #include "AssimpPCH.h" #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER #include <vector> #include <sstream> -using namespace std; -#include "OgreImporter.hpp" -#include "irrXMLWrapper.h" +#include "OgreImporter.h" #include "TinyFormatter.h" +using namespace std; + namespace Assimp { namespace Ogre { +static const string partComment = "//"; +static const string partBlockStart = "{"; +static const string partBlockEnd = "}"; - -aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const +aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string materialName) { - const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene - (void)m_CurrentScene; - - /*For bettetr understanding of the material parser, here is a material example file: - - material Sarg - { - receive_shadows on - technique - { - pass - { - ambient 0.500000 0.500000 0.500000 1.000000 - diffuse 0.640000 0.640000 0.640000 1.000000 - specular 0.500000 0.500000 0.500000 1.000000 12.500000 - emissive 0.000000 0.000000 0.000000 1.000000 - texture_unit - { - texture SargTextur.tga - tex_address_mode wrap - filtering linear linear none - } - } - } + /// @todo Should we return null ptr here or a empty material? + if (materialName.empty()) { + return new aiMaterial(); } - */ + // Full reference and examples of Ogre Material Script + // can be found from http://www.ogre3d.org/docs/manual/manual_14.html /*and here is another one: @@ -115,332 +92,450 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const } */ - //Read the file into memory and put it in a stringstream stringstream ss; - {// after this block, the temporarly loaded data will be released - - /* - We have 3 guesses for the Material filename: - - the Material Name - - the Name of the mesh file - - the DefaultMaterialLib (which you can set before importing) - */ + + // Scope for scopre_ptr auto release + { + /* There are three .material options in priority order: + 1) File with the material name (materialName) + 2) File with the mesh files base name (pFile) + 3) Optional user defined material library file (m_userDefinedMaterialLibFile) */ + std::vector<string> potentialFiles; + potentialFiles.push_back(materialName + ".material"); + potentialFiles.push_back(pFile.substr(0, pFile.rfind(".mesh")) + ".material"); + if (!m_userDefinedMaterialLibFile.empty()) + potentialFiles.push_back(m_userDefinedMaterialLibFile); - IOStream* MatFilePtr=m_CurrentIOHandler->Open(MaterialName+".material"); - if(NULL==MatFilePtr) + IOStream *materialFile = 0; + for(size_t i=0; i<potentialFiles.size(); ++i) { - //the filename typically ends with .mesh or .mesh.xml - const string MaterialFileName=m_CurrentFilename.substr(0, m_CurrentFilename.rfind(".mesh"))+".material"; - - MatFilePtr=m_CurrentIOHandler->Open(MaterialFileName); - if(NULL==MatFilePtr) - { - //try the default mat Library - if(NULL==MatFilePtr) - { - - MatFilePtr=m_CurrentIOHandler->Open(m_MaterialLibFilename); - if(NULL==MatFilePtr) - { - DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opened, Material will not be loaded!"); - return NULL; - } - } + materialFile = pIOHandler->Open(potentialFiles[i]); + if (materialFile) { + break; } + DefaultLogger::get()->debug(Formatter::format() << "Source file for material '" << materialName << "' " << potentialFiles[i] << " does not exist"); + } + if (!materialFile) + { + /// @todo Should we return null ptr here or a empty material? + DefaultLogger::get()->error(Formatter::format() << "Failed to find source file for material '" << materialName << "'"); + return new aiMaterial(); + } + + boost::scoped_ptr<IOStream> stream(materialFile); + if (stream->FileSize() == 0) + { + /// @todo Should we return null ptr here or a empty material? + DefaultLogger::get()->warn(Formatter::format() << "Source file for material '" << materialName << "' is empty (size is 0 bytes)"); + return new aiMaterial(); } - boost::scoped_ptr<IOStream> MaterialFile(MatFilePtr); - vector<char> FileData(MaterialFile->FileSize()); - MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1); - BaseImporter::ConvertToUTF8(FileData); - ss << &FileData[0]; + // Read bytes + vector<char> data(stream->FileSize()); + stream->Read(&data[0], stream->FileSize(), 1); + + // Convert to UTF-8 and terminate the string for ss + BaseImporter::ConvertToUTF8(data); + data.push_back('\0'); + + ss << &data[0]; } + + DefaultLogger::get()->debug("Reading material '" + materialName + "'"); - //create the material - aiMaterial *NewMaterial=new aiMaterial(); + aiMaterial *material = new aiMaterial(); + m_textures.clear(); + + aiString ts(materialName); + material->AddProperty(&ts, AI_MATKEY_NAME); - aiString ts(MaterialName.c_str()); - NewMaterial->AddProperty(&ts, AI_MATKEY_NAME); + // The stringstream will push words from a line until newline. + // It will also trim whitespace from line start and between words. + string linePart; + ss >> linePart; + + const string partMaterial = "material"; + const string partTechnique = "technique"; - string Line; - ss >> Line; -// unsigned int Level=0;//Hierarchielevels in the material file, like { } blocks into another while(!ss.eof()) { - if(Line=="material") + // Skip commented lines + if (linePart == partComment) + { + string postComment = NextAfterNewLine(ss, linePart); + DefaultLogger::get()->debug("//" + postComment + " (comment line ignored)"); + continue; + } + if (linePart != partMaterial) + { + ss >> linePart; + continue; + } + + ss >> linePart; + if (linePart != materialName) + { + //DefaultLogger::get()->debug(Formatter::format() << "Found material '" << linePart << "' that does not match at index " << ss.tellg()); + ss >> linePart; + continue; + } + + NextAfterNewLine(ss, linePart); + if (linePart != partBlockStart) { - ss >> Line; - if(Line==MaterialName)//Load the next material + DefaultLogger::get()->error(Formatter::format() << "Invalid material: block start missing near index " << ss.tellg()); + return material; + } + + DefaultLogger::get()->debug("material '" + materialName + "'"); + + while(linePart != partBlockEnd) + { + // Proceed to the first technique + ss >> linePart; + + if (linePart == partTechnique) { - string RestOfLine; - getline(ss, RestOfLine);//ignore the rest of the line - ss >> Line; + string techniqueName = SkipLine(ss); + ReadTechnique(Trim(techniqueName), ss, material); + } - if(Line!="{") + // Read informations from a custom material + /** @todo This "set $x y" does not seem to be a official Ogre material system feature. + Materials can inherit other materials and override texture units by using the (unique) + parent texture unit name in your cloned material. + This is not yet supported and below code is probably some hack from the original + author of this Ogre importer. Should be removed? */ + if (linePart=="set") + { + ss >> linePart; + if (linePart=="$specular")//todo load this values: { - DefaultLogger::get()->warn("empyt material!"); - return NULL; } - - while(Line!="}")//read until the end of the material + else if (linePart=="$diffuse") { - //Proceed to the first technique - ss >> Line; - if(Line=="technique") - { - ReadTechnique(ss, NewMaterial); + } + else if (linePart=="$ambient") + { + } + else if (linePart=="$colormap") + { + ss >> linePart; + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); + } + else if (linePart=="$normalmap") + { + ss >> linePart; + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); + } + else if (linePart=="$shininess_strength") + { + ss >> linePart; + float Shininess = fast_atof(linePart.c_str()); + material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH); + } + else if (linePart=="$shininess_exponent") + { + ss >> linePart; + float Shininess = fast_atof(linePart.c_str()); + material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS); + } + //Properties from Venetica: + else if (linePart=="$diffuse_map") + { + ss >> linePart; + if (linePart[0] == '"')// "file" -> file + linePart = linePart.substr(1, linePart.size()-2); + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); + } + else if (linePart=="$specular_map") + { + ss >> linePart; + if (linePart[0] == '"')// "file" -> file + linePart = linePart.substr(1, linePart.size()-2); + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0)); + } + else if (linePart=="$normal_map") + { + ss >> linePart; + if (linePart[0]=='"')// "file" -> file + linePart = linePart.substr(1, linePart.size()-2); + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); + } + else if (linePart=="$light_map") + { + ss >> linePart; + if (linePart[0]=='"') { + linePart = linePart.substr(1, linePart.size() - 2); } - - DefaultLogger::get()->info(Line); - //read informations from a custom material: - if(Line=="set") - { - ss >> Line; - if(Line=="$specular")//todo load this values: - { - } - if(Line=="$diffuse") - { - } - if(Line=="$ambient") - { - } - if(Line=="$colormap") - { - ss >> Line; - aiString ts(Line.c_str()); - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); - } - if(Line=="$normalmap") - { - ss >> Line; - aiString ts(Line.c_str()); - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); - } - - if(Line=="$shininess_strength") - { - ss >> Line; - float Shininess=fast_atof(Line.c_str()); - NewMaterial->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH); - } - - if(Line=="$shininess_exponent") - { - ss >> Line; - float Shininess=fast_atof(Line.c_str()); - NewMaterial->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS); - } - - //Properties from Venetica: - if(Line=="$diffuse_map") - { - ss >> Line; - if(Line[0]=='"')// "file" -> file - Line=Line.substr(1, Line.size()-2); - aiString ts(Line.c_str()); - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); - } - if(Line=="$specular_map") - { - ss >> Line; - if(Line[0]=='"')// "file" -> file - Line=Line.substr(1, Line.size()-2); - aiString ts(Line.c_str()); - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0)); - } - if(Line=="$normal_map") - { - ss >> Line; - if(Line[0]=='"')// "file" -> file - Line=Line.substr(1, Line.size()-2); - aiString ts(Line.c_str()); - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); - } - if(Line=="$light_map") - { - ss >> Line; - if(Line[0]=='"')// "file" -> file - Line=Line.substr(1, Line.size()-2); - aiString ts(Line.c_str()); - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0)); - } - } - }//end of material - } - else {} //this is the wrong material, proceed the file until we reach the next material + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0)); + } + } } - ss >> Line; + ss >> linePart; + } + + return material; +} + +bool OgreImporter::ReadTechnique(const std::string &techniqueName, stringstream &ss, aiMaterial *material) +{ + string linePart; + ss >> linePart; + + if (linePart != partBlockStart) + { + DefaultLogger::get()->error(Formatter::format() << "Invalid material: Technique block start missing near index " << ss.tellg()); + return false; } - return NewMaterial; + DefaultLogger::get()->debug(" technique '" + techniqueName + "'"); + + const string partPass = "pass"; + + while(linePart != partBlockEnd) + { + ss >> linePart; + + // Skip commented lines + if (linePart == partComment) + { + string postComment = SkipLine(ss); + DefaultLogger::get()->debug(" //" + postComment + " (comment line ignored)"); + continue; + } + + /// @todo Techniques have other attributes than just passes. + if (linePart == partPass) + { + string passName = SkipLine(ss); + ReadPass(Trim(passName), ss, material); + } + } + return true; } -void OgreImporter::ReadTechnique(stringstream &ss, aiMaterial* NewMaterial) const +bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMaterial *material) { - unsigned int CurrentDiffuseTextureId=0; - unsigned int CurrentSpecularTextureId=0; - unsigned int CurrentNormalTextureId=0; - unsigned int CurrentLightTextureId=0; + string linePart; + ss >> linePart; + + if (linePart != partBlockStart) + { + DefaultLogger::get()->error(Formatter::format() << "Invalid material: Pass block start missing near index " << ss.tellg()); + return false; + } + DefaultLogger::get()->debug(" pass '" + passName + "'"); - string RestOfLine; - getline(ss, RestOfLine);//ignore the rest of the line + const string partAmbient = "ambient"; + const string partDiffuse = "diffuse"; + const string partSpecular = "specular"; + const string partEmissive = "emissive"; + const string partTextureUnit = "texture_unit"; - string Line; - ss >> Line; - if(Line!="{") + while(linePart != partBlockEnd) { - DefaultLogger::get()->warn("empty technique!"); - return; + ss >> linePart; + + // Skip commented lines + if (linePart == partComment) + { + string postComment = SkipLine(ss); + DefaultLogger::get()->debug(" //" + postComment + " (comment line ignored)"); + continue; + } + + // Colors + /// @todo Support alpha via aiColor4D. + if (linePart == partAmbient || linePart == partDiffuse || linePart == partSpecular || linePart == partEmissive) + { + float r, g, b; + ss >> r >> g >> b; + const aiColor3D color(r, g, b); + + DefaultLogger::get()->debug(Formatter::format() << " " << linePart << " " << r << " " << g << " " << b); + + if (linePart == partAmbient) + { + material->AddProperty(&color, 1, AI_MATKEY_COLOR_AMBIENT); + } + else if (linePart == partDiffuse) + { + material->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE); + } + else if (linePart == partSpecular) + { + material->AddProperty(&color, 1, AI_MATKEY_COLOR_SPECULAR); + } + else if (linePart == partEmissive) + { + material->AddProperty(&color, 1, AI_MATKEY_COLOR_EMISSIVE); + } + } + else if (linePart == partTextureUnit) + { + string textureUnitName = SkipLine(ss); + ReadTextureUnit(Trim(textureUnitName), ss, material); + } + } + return true; +} + +bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstream &ss, aiMaterial *material) +{ + string linePart; + ss >> linePart; + + if (linePart != partBlockStart) + { + DefaultLogger::get()->error(Formatter::format() << "Invalid material: Texture unit block start missing near index " << ss.tellg()); + return false; } - while(Line!="}")//read until the end of the technique + + DefaultLogger::get()->debug(" texture_unit '" + textureUnitName + "'"); + + const string partTexture = "texture"; + const string partTextCoordSet = "tex_coord_set"; + const string partColorOp = "colour_op"; + + aiTextureType textureType = aiTextureType_NONE; + std::string textureRef; + int uvCoord = 0; + + while(linePart != partBlockEnd) { - ss >> Line; - if(Line=="pass") + ss >> linePart; + + // Skip commented lines + if (linePart == partComment) + { + string postComment = SkipLine(ss); + DefaultLogger::get()->debug(" //" + postComment + " (comment line ignored)"); + continue; + } + + if (linePart == partTexture) { - getline(ss, RestOfLine);//ignore the rest of the line + ss >> linePart; + textureRef = linePart; - ss >> Line; - if(Line!="{") + // User defined Assimp config property to detect texture type from filename. + if (m_detectTextureTypeFromFilename) { - DefaultLogger::get()->warn("empty pass!"); - return; + size_t posSuffix = textureRef.find_last_of("."); + size_t posUnderscore = textureRef.find_last_of("_"); + + if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) + { + string identifier = Ogre::ToLower(textureRef.substr(posUnderscore, posSuffix - posUnderscore)); + DefaultLogger::get()->debug(Formatter::format() << "Detecting texture type from filename postfix '" << identifier << "'"); + + if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") + { + textureType = aiTextureType_NORMALS; + } + else if (identifier == "_s" || identifier == "_spec" || identifier == "_specular" || identifier == "_specularmap") + { + textureType = aiTextureType_SPECULAR; + } + else if (identifier == "_l" || identifier == "_light" || identifier == "_lightmap" || identifier == "_occ" || identifier == "_occlusion") + { + textureType = aiTextureType_LIGHTMAP; + } + else if (identifier == "_disp" || identifier == "_displacement") + { + textureType = aiTextureType_DISPLACEMENT; + } + else + { + textureType = aiTextureType_DIFFUSE; + } + } + else + { + textureType = aiTextureType_DIFFUSE; + } } - while(Line!="}")//read until the end of the pass + // Detect from texture unit name. This cannot be too broad as + // authors might give names like "LightSaber" or "NormalNinja". + else { - ss >> Line; - if(Line=="ambient") + string unitNameLower = Ogre::ToLower(textureUnitName); + if (unitNameLower.find("normalmap") != string::npos) { - float r,g,b; - ss >> r >> g >> b; - const aiColor3D Color(r,g,b); - NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_AMBIENT); + textureType = aiTextureType_NORMALS; } - else if(Line=="diffuse") + else if (unitNameLower.find("specularmap") != string::npos) { - float r,g,b; - ss >> r >> g >> b; - const aiColor3D Color(r,g,b); - NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_DIFFUSE); + textureType = aiTextureType_SPECULAR; } - else if(Line=="specular") + else if (unitNameLower.find("lightmap") != string::npos) { - float r,g,b; - ss >> r >> g >> b; - const aiColor3D Color(r,g,b); - NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_SPECULAR); + textureType = aiTextureType_LIGHTMAP; } - else if(Line=="emmisive") + else if (unitNameLower.find("displacementmap") != string::npos) { - float r,g,b; - ss >> r >> g >> b; - const aiColor3D Color(r,g,b); - NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_EMISSIVE); + textureType = aiTextureType_DISPLACEMENT; } - else if(Line=="texture_unit") + else { - getline(ss, RestOfLine);//ignore the rest of the line - - std::string TextureName; - int TextureType=-1; - int UvSet=0; - - ss >> Line; - if(Line!="{") - throw DeadlyImportError("empty texture unit!"); - while(Line!="}")//read until the end of the texture_unit - { - ss >> Line; - if(Line=="texture") - { - ss >> Line; - TextureName=Line; - - if(m_TextureTypeFromFilename) - { - if(Line.find("_n.")!=string::npos)// Normalmap - { - TextureType=aiTextureType_NORMALS; - } - else if(Line.find("_s.")!=string::npos)// Specularmap - { - TextureType=aiTextureType_SPECULAR; - } - else if(Line.find("_l.")!=string::npos)// Lightmap - { - TextureType=aiTextureType_LIGHTMAP; - } - else// colormap - { - TextureType=aiTextureType_DIFFUSE; - } - } - else - { - TextureType=aiTextureType_DIFFUSE; - } - } - else if(Line=="tex_coord_set") - { - ss >> UvSet; - } - else if(Line=="colour_op")//TODO implement this - { - /* - ss >> Line; - if("replace"==Line)//I don't think, assimp has something for this... - { - } - else if("modulate"==Line) - { - //TODO: set value - //NewMaterial->AddProperty(aiTextureOp_Multiply) - } - */ - } - - }//end of texture unit - Line="";//clear the } that would end the outer loop - - //give the texture to assimp: - - aiString ts(TextureName.c_str()); - switch(TextureType) - { - case aiTextureType_DIFFUSE: - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, CurrentDiffuseTextureId)); - NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentDiffuseTextureId)); - CurrentDiffuseTextureId++; - break; - case aiTextureType_NORMALS: - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, CurrentNormalTextureId)); - NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentNormalTextureId)); - CurrentNormalTextureId++; - break; - case aiTextureType_SPECULAR: - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SPECULAR, CurrentSpecularTextureId)); - NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentSpecularTextureId)); - CurrentSpecularTextureId++; - break; - case aiTextureType_LIGHTMAP: - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, CurrentLightTextureId)); - NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentLightTextureId)); - CurrentLightTextureId++; - break; - default: - DefaultLogger::get()->warn("Invalid Texture Type!"); - break; - } + textureType = aiTextureType_DIFFUSE; } } - Line="";//clear the } that would end the outer loop } - }//end of technique -} + else if (linePart == partTextCoordSet) + { + ss >> uvCoord; + } + /// @todo Implement + else if(linePart == partColorOp) + { + /* + ss >> linePart; + if("replace"==linePart)//I don't think, assimp has something for this... + { + } + else if("modulate"==linePart) + { + //TODO: set value + //material->AddProperty(aiTextureOp_Multiply) + } + */ + } + } + + if (textureRef.empty()) + { + DefaultLogger::get()->warn("Texture reference is empty, ignoring texture_unit."); + return false; + } + if (textureType == aiTextureType_NONE) + { + DefaultLogger::get()->warn("Failed to detect texture type for '" + textureRef + "', ignoring texture_unit."); + return false; + } + unsigned int textureTypeIndex = m_textures[textureType]; + m_textures[textureType]++; + + DefaultLogger::get()->debug(Formatter::format() << " texture '" << textureRef << "' type " << textureType + << " index " << textureTypeIndex << " UV " << uvCoord); + + aiString assimpTextureRef(textureRef); + material->AddProperty(&assimpTextureRef, AI_MATKEY_TEXTURE(textureType, textureTypeIndex)); + material->AddProperty(&uvCoord, 1, AI_MATKEY_UVWSRC(textureType, textureTypeIndex)); + + return true; +} -}//namespace Ogre -}//namespace Assimp +} // Ogre +} // Assimp -#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER +#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER diff --git a/src/3rdparty/assimp/code/OgreMesh.cpp b/src/3rdparty/assimp/code/OgreMesh.cpp index 109056e21..5c7a12398 100644 --- a/src/3rdparty/assimp/code/OgreMesh.cpp +++ b/src/3rdparty/assimp/code/OgreMesh.cpp @@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER -#include "OgreImporter.hpp" +#include "OgreImporter.h" #include "TinyFormatter.h" using namespace std; @@ -52,466 +52,518 @@ namespace Assimp namespace Ogre { - -void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader) +void OgreImporter::ReadSubMesh(const unsigned int submeshIndex, SubMesh &submesh, XmlReader *reader) { - if(Reader->getAttributeValue("usesharedvertices")) - theSubMesh.SharedData=GetAttribute<bool>(Reader, "usesharedvertices"); + if (reader->getAttributeValue("material")) { + submesh.MaterialName = GetAttribute<string>(reader, "material"); + } + if (reader->getAttributeValue("use32bitindexes")) { + submesh.Use32bitIndexes = GetAttribute<bool>(reader, "use32bitindexes"); + } + if (reader->getAttributeValue("usesharedvertices")) { + submesh.UseSharedGeometry = GetAttribute<bool>(reader, "usesharedvertices"); + } + + DefaultLogger::get()->debug(Formatter::format() << "Reading submesh " << submeshIndex); + DefaultLogger::get()->debug(Formatter::format() << " - Material '" << submesh.MaterialName << "'"); + DefaultLogger::get()->debug(Formatter::format() << " - Shader geometry = " << (submesh.UseSharedGeometry ? "true" : "false") << + ", 32bit indexes = " << (submesh.Use32bitIndexes ? "true" : "false")); - XmlRead(Reader); //TODO: maybe we have alsways just 1 faces and 1 geometry and always in this order. this loop will only work correct, when the order //of faces and geometry changed, and not if we have more than one of one - while( Reader->getNodeName()==string("faces") - || Reader->getNodeName()==string("geometry") - || Reader->getNodeName()==string("boneassignments")) + /// @todo Fix above comment with better read logic below + + NextNode(reader); + string currentNodeName = reader->getNodeName(); + + const string nnFaces = "faces"; + const string nnFace = "face"; + const string nnGeometry = "geometry"; + const string nnBoneAssignments = "boneassignments"; + const string nnVertexBuffer = "vertexbuffer"; + + bool quadWarned = false; + + while(currentNodeName == nnFaces || + currentNodeName == nnGeometry || + currentNodeName == nnBoneAssignments) { - if(string(Reader->getNodeName())=="faces")//Read the face list + if (currentNodeName == nnFaces) { - //some info logging: - unsigned int NumFaces=GetAttribute<int>(Reader, "count"); - ostringstream ss; ss <<"Submesh has " << NumFaces << " Faces."; - DefaultLogger::get()->debug(ss.str()); + unsigned int numFaces = GetAttribute<unsigned int>(reader, "count"); + + NextNode(reader); + currentNodeName = reader->getNodeName(); - while(XmlRead(Reader) && Reader->getNodeName()==string("face")) + while(currentNodeName == nnFace) { Face NewFace; - NewFace.VertexIndices[0]=GetAttribute<int>(Reader, "v1"); - NewFace.VertexIndices[1]=GetAttribute<int>(Reader, "v2"); - NewFace.VertexIndices[2]=GetAttribute<int>(Reader, "v3"); - if(Reader->getAttributeValue("v4"))//this should be supported in the future - { - DefaultLogger::get()->warn("Submesh has quads, only traingles are supported!"); - //throw DeadlyImportError("Submesh has quads, only traingles are supported!"); + NewFace.VertexIndices[0] = GetAttribute<int>(reader, "v1"); + NewFace.VertexIndices[1] = GetAttribute<int>(reader, "v2"); + NewFace.VertexIndices[2] = GetAttribute<int>(reader, "v3"); + + /// @todo Support quads + if (!quadWarned && reader->getAttributeValue("v4")) { + DefaultLogger::get()->warn("Submesh has quads, only triangles are supported at the moment!"); } - theSubMesh.FaceList.push_back(NewFace); + + submesh.Faces.push_back(NewFace); + + // Advance + NextNode(reader); + currentNodeName = reader->getNodeName(); } - }//end of faces - else if(string(Reader->getNodeName())=="geometry")//Read the vertexdata - { - //some info logging: - unsigned int NumVertices=GetAttribute<int>(Reader, "vertexcount"); - ostringstream ss; ss<<"VertexCount: " << NumVertices; - DefaultLogger::get()->debug(ss.str()); - - //General Informations about vertices - XmlRead(Reader); - while(Reader->getNodeName()==string("vertexbuffer")) + if (submesh.Faces.size() == numFaces) { - ReadVertexBuffer(theSubMesh, Reader, NumVertices); + DefaultLogger::get()->debug(Formatter::format() << " - Faces " << numFaces); } - - //some error checking on the loaded data - if(!theSubMesh.HasPositions) - throw DeadlyImportError("No positions could be loaded!"); - - if(theSubMesh.HasNormals && theSubMesh.Normals.size() != NumVertices) - throw DeadlyImportError("Wrong Number of Normals loaded!"); - - if(theSubMesh.HasTangents && theSubMesh.Tangents.size() != NumVertices) - throw DeadlyImportError("Wrong Number of Tangents loaded!"); - - for(unsigned int i=0; i<theSubMesh.Uvs.size(); ++i) + else { - if(theSubMesh.Uvs[i].size() != NumVertices) - throw DeadlyImportError("Wrong Number of Uvs loaded!"); + throw DeadlyImportError(Formatter::format() << "Read only " << submesh.Faces.size() << " faces when should have read " << numFaces); } + } + else if (currentNodeName == nnGeometry) + { + unsigned int numVertices = GetAttribute<int>(reader, "vertexcount"); - }//end of "geometry - - - else if(Reader->getNodeName()==string("boneassignments")) + NextNode(reader); + while(string(reader->getNodeName()) == nnVertexBuffer) { + ReadVertexBuffer(submesh, reader, numVertices); + } + } + else if (reader->getNodeName() == nnBoneAssignments) { - ReadBoneWeights(theSubMesh, Reader); + ReadBoneWeights(submesh, reader); } + + currentNodeName = reader->getNodeName(); } - DefaultLogger::get()->debug((Formatter::format(), - "Positionen: ",theSubMesh.Positions.size(), - " Normale: ",theSubMesh.Normals.size(), - " TexCoords: ",theSubMesh.Uvs.size(), - " Tantents: ",theSubMesh.Tangents.size() - )); - DefaultLogger::get()->warn(Reader->getNodeName()); } - -void OgreImporter::ReadVertexBuffer(SubMesh &theSubMesh, XmlReader *Reader, unsigned int NumVertices) +void OgreImporter::ReadVertexBuffer(SubMesh &submesh, XmlReader *reader, const unsigned int numVertices) { - DefaultLogger::get()->debug("new Vertex Buffer"); - - bool ReadPositions=false; - bool ReadNormals=false; - bool ReadTangents=false; - unsigned int NumUvs=0; + DefaultLogger::get()->debug(Formatter::format() << "Reading vertex buffer with " << numVertices << " vertices"); + + submesh.HasGeometry = true; - //-------------------- check, what we need to read: -------------------------------- - if(Reader->getAttributeValue("positions") && GetAttribute<bool>(Reader, "positions")) + if (reader->getAttributeValue("positions") && GetAttribute<bool>(reader, "positions")) { - ReadPositions=theSubMesh.HasPositions=true; - theSubMesh.Positions.reserve(NumVertices); - DefaultLogger::get()->debug("reading positions"); + submesh.HasPositions = true; + submesh.Positions.reserve(numVertices); + DefaultLogger::get()->debug(" - Has positions"); } - if(Reader->getAttributeValue("normals") && GetAttribute<bool>(Reader, "normals")) + if (reader->getAttributeValue("normals") && GetAttribute<bool>(reader, "normals")) { - ReadNormals=theSubMesh.HasNormals=true; - theSubMesh.Normals.reserve(NumVertices); - DefaultLogger::get()->debug("reading normals"); + submesh.HasNormals = true; + submesh.Normals.reserve(numVertices); + DefaultLogger::get()->debug(" - Has normals"); } - if(Reader->getAttributeValue("tangents") && GetAttribute<bool>(Reader, "tangents")) + if (reader->getAttributeValue("tangents") && GetAttribute<bool>(reader, "tangents")) { - ReadTangents=theSubMesh.HasTangents=true; - theSubMesh.Tangents.reserve(NumVertices); - DefaultLogger::get()->debug("reading tangents"); + submesh.HasTangents = true; + submesh.Tangents.reserve(numVertices); + DefaultLogger::get()->debug(" - Has tangents"); } - - if(Reader->getAttributeValue("texture_coords")) + if (reader->getAttributeValue("texture_coords")) { - NumUvs=GetAttribute<unsigned int>(Reader, "texture_coords"); - theSubMesh.Uvs.resize(NumUvs); - for(unsigned int i=0; i<theSubMesh.Uvs.size(); ++i) theSubMesh.Uvs[i].reserve(NumVertices); - DefaultLogger::get()->debug("reading texture coords"); + submesh.Uvs.resize(GetAttribute<unsigned int>(reader, "texture_coords")); + for(size_t i=0, len=submesh.Uvs.size(); i<len; ++i) { + submesh.Uvs[i].reserve(numVertices); + } + DefaultLogger::get()->debug(Formatter::format() << " - Has " << submesh.Uvs.size() << " texture coords"); } - //___________________________________________________________________ + if (!submesh.HasPositions) { + throw DeadlyImportError("Vertex buffer does not contain positions!"); + } - //check if we will load anything - if(!( ReadPositions || ReadNormals || ReadTangents || (NumUvs>0) )) - DefaultLogger::get()->warn("vertexbuffer seams to be empty!"); + const string nnVertex = "vertex"; + const string nnPosition = "position"; + const string nnNormal = "normal"; + const string nnTangent = "tangent"; + const string nnBinormal = "binormal"; + const string nnTexCoord = "texcoord"; + const string nnColorDiffuse = "colour_diffuse"; + const string nnColorSpecular = "colour_specular"; - - //read all the vertices: - XmlRead(Reader); - - /*it might happen, that we have more than one attribute per vertex (they are not splitted to different buffers) - so the break condition is a bit tricky (well, IrrXML just sucks :( )*/ - while(Reader->getNodeName()==string("vertex") - ||Reader->getNodeName()==string("position") - ||Reader->getNodeName()==string("normal") - ||Reader->getNodeName()==string("tangent") - ||Reader->getNodeName()==string("texcoord") - ||Reader->getNodeName()==string("colour_diffuse")) + bool warnBinormal = true; + bool warnColorDiffuse = true; + bool warnColorSpecular = true; + + NextNode(reader); + string currentNodeName = reader->getNodeName(); + + /// @todo Make this loop nicer. + while(currentNodeName == nnVertex || + currentNodeName == nnPosition || + currentNodeName == nnNormal || + currentNodeName == nnTangent || + currentNodeName == nnBinormal || + currentNodeName == nnTexCoord || + currentNodeName == nnColorDiffuse || + currentNodeName == nnColorSpecular) { - if(Reader->getNodeName()==string("vertex")) - XmlRead(Reader);//Read an attribute tag + if (currentNodeName == nnVertex) + { + NextNode(reader); + currentNodeName = reader->getNodeName(); + } + + /// @todo Implement nnBinormal, nnColorDiffuse and nnColorSpecular - //Position - if(ReadPositions && Reader->getNodeName()==string("position")) + if (submesh.HasPositions && currentNodeName == nnPosition) { aiVector3D NewPos; - NewPos.x=GetAttribute<float>(Reader, "x"); - NewPos.y=GetAttribute<float>(Reader, "y"); - NewPos.z=GetAttribute<float>(Reader, "z"); - theSubMesh.Positions.push_back(NewPos); + NewPos.x = GetAttribute<float>(reader, "x"); + NewPos.y = GetAttribute<float>(reader, "y"); + NewPos.z = GetAttribute<float>(reader, "z"); + submesh.Positions.push_back(NewPos); } - - //Normal - else if(ReadNormals && Reader->getNodeName()==string("normal")) + else if (submesh.HasNormals && currentNodeName == nnNormal) { aiVector3D NewNormal; - NewNormal.x=GetAttribute<float>(Reader, "x"); - NewNormal.y=GetAttribute<float>(Reader, "y"); - NewNormal.z=GetAttribute<float>(Reader, "z"); - theSubMesh.Normals.push_back(NewNormal); + NewNormal.x = GetAttribute<float>(reader, "x"); + NewNormal.y = GetAttribute<float>(reader, "y"); + NewNormal.z = GetAttribute<float>(reader, "z"); + submesh.Normals.push_back(NewNormal); } - - //Tangent - else if(ReadTangents && Reader->getNodeName()==string("tangent")) + else if (submesh.HasTangents && currentNodeName == nnTangent) { aiVector3D NewTangent; - NewTangent.x=GetAttribute<float>(Reader, "x"); - NewTangent.y=GetAttribute<float>(Reader, "y"); - NewTangent.z=GetAttribute<float>(Reader, "z"); - theSubMesh.Tangents.push_back(NewTangent); + NewTangent.x = GetAttribute<float>(reader, "x"); + NewTangent.y = GetAttribute<float>(reader, "y"); + NewTangent.z = GetAttribute<float>(reader, "z"); + submesh.Tangents.push_back(NewTangent); } - - //Uv: - else if(NumUvs>0 && Reader->getNodeName()==string("texcoord")) + else if (submesh.Uvs.size() > 0 && currentNodeName == nnTexCoord) { - for(unsigned int i=0; i<NumUvs; ++i) + for(size_t i=0, len=submesh.Uvs.size(); i<len; ++i) { - if(Reader->getNodeName()!=string("texcoord")) - { - DefaultLogger::get()->warn(string("Not enough UVs in Vertex: ")+Reader->getNodeName()); + if (currentNodeName != nnTexCoord) { + throw DeadlyImportError("Vertex buffer declared more UVs than can be found in a vertex"); } + aiVector3D NewUv; - NewUv.x=GetAttribute<float>(Reader, "u"); - NewUv.y=GetAttribute<float>(Reader, "v")*(-1)+1;//flip the uv vertikal, blender exports them so! - theSubMesh.Uvs[i].push_back(NewUv); - XmlRead(Reader); + NewUv.x = GetAttribute<float>(reader, "u"); + NewUv.y = GetAttribute<float>(reader, "v") * (-1)+1; //flip the uv vertikal, blender exports them so! (ahem... @todo ????) + submesh.Uvs[i].push_back(NewUv); + + NextNode(reader); + currentNodeName = reader->getNodeName(); } - continue;//because we already read the next node... - } - - //Color: - //TODO: actually save this data! - else if(Reader->getNodeName()==string("colour_diffuse")) - { - //do nothing, because we not yet support them + // Continue main loop as above already read next node + continue; } - - //Attribute could not be read else { - DefaultLogger::get()->warn(string("Attribute was not read: ")+Reader->getNodeName()); + /// @todo Remove this stuff once implemented. We only want to log warnings once per element. + bool warn = true; + if (currentNodeName == nnBinormal) + { + if (warnBinormal) + { + warnBinormal = false; + } + else + { + warn = false; + } + } + else if (currentNodeName == nnColorDiffuse) + { + if (warnColorDiffuse) + { + warnColorDiffuse = false; + } + else + { + warn = false; + } + } + else if (currentNodeName == nnColorSpecular) + { + if (warnColorSpecular) + { + warnColorSpecular = false; + } + else + { + warn = false; + } + } + if (warn) { + DefaultLogger::get()->warn(string("Vertex buffer attribute read not implemented for element: ") + currentNodeName); + } } - XmlRead(Reader);//Read the Vertex tag + // Advance + NextNode(reader); + currentNodeName = reader->getNodeName(); } -} + DefaultLogger::get()->debug(Formatter::format() << + " - Positions " << submesh.Positions.size() << + " Normals " << submesh.Normals.size() << + " TexCoords " << submesh.Uvs.size() << + " Tangents " << submesh.Tangents.size()); -void OgreImporter::ReadBoneWeights(SubMesh &theSubMesh, XmlReader *Reader) -{ - theSubMesh.Weights.resize(theSubMesh.Positions.size()); - while(XmlRead(Reader) && Reader->getNodeName()==string("vertexboneassignment")) + // Sanity checks + if (submesh.HasNormals && submesh.Normals.size() != numVertices) { + throw DeadlyImportError(Formatter::format() << "Read only " << submesh.Normals.size() << " normals when should have read " << numVertices); + } + if (submesh.HasTangents && submesh.Tangents.size() != numVertices) { + throw DeadlyImportError(Formatter::format() << "Read only " << submesh.Tangents.size() << " tangents when should have read " << numVertices); + } + for(unsigned int i=0; i<submesh.Uvs.size(); ++i) { - Weight NewWeight; - unsigned int VertexId=GetAttribute<int>(Reader, "vertexindex"); - NewWeight.BoneId=GetAttribute<int>(Reader, "boneindex"); - NewWeight.Value=GetAttribute<float>(Reader, "weight"); - //calculate the number of bones used (this is the highest id +1 becuase bone ids start at 0) - theSubMesh.BonesUsed=max(theSubMesh.BonesUsed, NewWeight.BoneId+1); - - theSubMesh.Weights[VertexId].push_back(NewWeight); + if (submesh.Uvs[i].size() != numVertices) { + throw DeadlyImportError(Formatter::format() << "Read only " << submesh.Uvs[i].size() + << " uvs for uv index " << i << " when should have read " << numVertices); + } } } - - -void OgreImporter::ProcessSubMesh(SubMesh &theSubMesh, SubMesh &theSharedGeometry) +void OgreImporter::ReadBoneWeights(SubMesh &submesh, XmlReader *reader) { - //---------------Make all Vertexes unique: (this is required by assimp)----------------------- - vector<Face> UniqueFaceList(theSubMesh.FaceList.size()); - unsigned int UniqueVertexCount=theSubMesh.FaceList.size()*3;//*3 because each face consists of 3 vertexes, because we only support triangles^^ + submesh.Weights.resize(submesh.Positions.size()); - vector<aiVector3D> UniquePositions(UniqueVertexCount); + unsigned int numRead = 0; + const string nnVertexBoneAssignment = "vertexboneassignment"; - vector<aiVector3D> UniqueNormals(UniqueVertexCount); + NextNode(reader); + while(CurrentNodeNameEquals(reader, nnVertexBoneAssignment)) + { + numRead++; - vector<aiVector3D> UniqueTangents(UniqueVertexCount); + BoneWeight weight; + weight.Id = GetAttribute<int>(reader, "boneindex"); + weight.Value = GetAttribute<float>(reader, "weight"); + + //calculate the number of bones used (this is the highest id +1 becuase bone ids start at 0) + /// @todo This can probably be refactored to something else. + submesh.BonesUsed = max(submesh.BonesUsed, weight.Id+1); - vector< vector<Weight> > UniqueWeights(UniqueVertexCount); + const unsigned int vertexId = GetAttribute<int>(reader, "vertexindex"); + submesh.Weights[vertexId].push_back(weight); + + NextNode(reader); + } + DefaultLogger::get()->debug(Formatter::format() << " - Bone weights " << numRead); +} - vector< vector<aiVector3D> > UniqueUvs(theSubMesh.Uvs.size()); - for(unsigned int i=0; i<UniqueUvs.size(); ++i) UniqueUvs[i].resize(UniqueVertexCount); +void OgreImporter::ProcessSubMesh(SubMesh &submesh, SubMesh &sharedGeometry) +{ + // Make all vertexes unique. Required by Assimp. + vector<Face> uniqueFaceList(submesh.Faces.size()); + unsigned int uniqueVertexCount = submesh.Faces.size() * 3; + vector<aiVector3D> uniquePositions(uniqueVertexCount); + vector<aiVector3D> uniqueNormals(uniqueVertexCount); + vector<aiVector3D> uniqueTangents(uniqueVertexCount); + vector<vector<BoneWeight> > uniqueWeights(uniqueVertexCount); + vector<vector<aiVector3D> > uniqueUvs(submesh.UseSharedGeometry ? sharedGeometry.Uvs.size() : submesh.Uvs.size()); - //Support for shared data: - /*We can use this loop to copy vertex informations from the shared data pool. In order to do so - we just use a reference to a submodel instead of our submodel itself*/ + for(size_t uvi=0; uvi<uniqueUvs.size(); ++uvi) { + uniqueUvs[uvi].resize(uniqueVertexCount); + } - SubMesh& VertexSource= theSubMesh.SharedData ? theSharedGeometry : theSubMesh; - if(theSubMesh.SharedData)//copy vertexinformations to our mesh: + /* Support for shared geometry. + We can use this loop to copy vertex informations from the shared data pool. In order to do so + we just use a reference to a submodel instead of our submodel itself */ + SubMesh &vertexSource = (submesh.UseSharedGeometry ? sharedGeometry : submesh); + if (submesh.UseSharedGeometry) { - theSubMesh.HasPositions=theSharedGeometry.HasPositions; - theSubMesh.HasNormals=theSharedGeometry.HasNormals; - theSubMesh.HasTangents=theSharedGeometry.HasTangents; - - theSubMesh.BonesUsed=theSharedGeometry.BonesUsed; - - UniqueUvs.resize(theSharedGeometry.Uvs.size()); - for(unsigned int i=0; i<UniqueUvs.size(); ++i) UniqueUvs[i].resize(UniqueVertexCount); + submesh.HasPositions = sharedGeometry.HasPositions; + submesh.HasNormals = sharedGeometry.HasNormals; + submesh.HasTangents = sharedGeometry.HasTangents; + submesh.BonesUsed = sharedGeometry.BonesUsed; } - for(unsigned int i=0; i<theSubMesh.FaceList.size(); ++i) + for (size_t i=0, flen=submesh.Faces.size(); i<flen; ++i) { - //We precalculate the index vlaues her, because we need them in all vertex attributes - unsigned int Vertex1=theSubMesh.FaceList[i].VertexIndices[0]; - unsigned int Vertex2=theSubMesh.FaceList[i].VertexIndices[1]; - unsigned int Vertex3=theSubMesh.FaceList[i].VertexIndices[2]; + const Face &face = submesh.Faces[i]; - UniquePositions[3*i+0]=VertexSource.Positions[Vertex1]; - UniquePositions[3*i+1]=VertexSource.Positions[Vertex2]; - UniquePositions[3*i+2]=VertexSource.Positions[Vertex3]; + // We pre calculate the index values here, + // because we need them in all vertex attributes. + unsigned int v1 = face.VertexIndices[0]; + unsigned int v2 = face.VertexIndices[1]; + unsigned int v3 = face.VertexIndices[2]; - if(VertexSource.HasNormals) + size_t pos = i*3; + + uniqueFaceList[i].VertexIndices[0] = pos; + uniqueFaceList[i].VertexIndices[1] = pos + 1; + uniqueFaceList[i].VertexIndices[2] = pos + 2; + + uniquePositions[pos] = vertexSource.Positions[v1]; + uniquePositions[pos+1] = vertexSource.Positions[v2]; + uniquePositions[pos+2] = vertexSource.Positions[v3]; + + if (vertexSource.HasNormals) { - UniqueNormals[3*i+0]=VertexSource.Normals[Vertex1]; - UniqueNormals[3*i+1]=VertexSource.Normals[Vertex2]; - UniqueNormals[3*i+2]=VertexSource.Normals[Vertex3]; + uniqueNormals[pos ] = vertexSource.Normals[v1]; + uniqueNormals[pos+1] = vertexSource.Normals[v2]; + uniqueNormals[pos+2] = vertexSource.Normals[v3]; } - if(VertexSource.HasTangents) + if (vertexSource.HasTangents) { - UniqueTangents[3*i+0]=VertexSource.Tangents[Vertex1]; - UniqueTangents[3*i+1]=VertexSource.Tangents[Vertex2]; - UniqueTangents[3*i+2]=VertexSource.Tangents[Vertex3]; + uniqueTangents[pos] = vertexSource.Tangents[v1]; + uniqueTangents[pos+1] = vertexSource.Tangents[v2]; + uniqueTangents[pos+2] = vertexSource.Tangents[v3]; } - if(UniqueUvs.size()>0) + for(size_t uvi=0; uvi<uniqueUvs.size(); ++uvi) { - for(unsigned int j=0; j<UniqueUvs.size(); ++j) - { - UniqueUvs[j][3*i+0]=VertexSource.Uvs[j][Vertex1]; - UniqueUvs[j][3*i+1]=VertexSource.Uvs[j][Vertex2]; - UniqueUvs[j][3*i+2]=VertexSource.Uvs[j][Vertex3]; - } + const std::vector<aiVector3D> &uv = vertexSource.Uvs[uvi]; + uniqueUvs[uvi][pos] = uv[v1]; + uniqueUvs[uvi][pos+1] = uv[v2]; + uniqueUvs[uvi][pos+2] = uv[v3]; } - if(VertexSource.Weights.size() > 0) + if (!vertexSource.Weights.empty()) { - UniqueWeights[3*i+0]=VertexSource.Weights[Vertex1]; - UniqueWeights[3*i+1]=VertexSource.Weights[Vertex2]; - UniqueWeights[3*i+2]=VertexSource.Weights[Vertex3]; + uniqueWeights[pos] = vertexSource.Weights[v1]; + uniqueWeights[pos+1] = vertexSource.Weights[v2]; + uniqueWeights[pos+2] = vertexSource.Weights[v3]; } - - //The indexvalues a just continuous numbers (0, 1, 2, 3, 4, 5, 6...) - UniqueFaceList[i].VertexIndices[0]=3*i+0; - UniqueFaceList[i].VertexIndices[1]=3*i+1; - UniqueFaceList[i].VertexIndices[2]=3*i+2; } - //_________________________________________________________________________________________ - - //now we have the unique datas, but want them in the SubMesh, so we swap all the containers: - //if we don't have one of them, we just swap empty containers, so everything is ok - theSubMesh.FaceList.swap(UniqueFaceList); - theSubMesh.Positions.swap(UniquePositions); - theSubMesh.Normals.swap(UniqueNormals); - theSubMesh.Tangents.swap(UniqueTangents); - theSubMesh.Uvs.swap(UniqueUvs); - theSubMesh.Weights.swap(UniqueWeights); - - - //------------- normalize weights ----------------------------- - //The Blender exporter doesn't care about whether the sum of all boneweights for a single vertex equals 1 or not, - //so we have to make this sure: - for(unsigned int VertexId=0; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices + // Now we have the unique data, but want them in the SubMesh, so we swap all the containers. + // If we don't have one of them, we just swap empty containers, so everything is ok. + submesh.Faces.swap(uniqueFaceList); + submesh.Positions.swap(uniquePositions); + submesh.Normals.swap(uniqueNormals); + submesh.Tangents.swap(uniqueTangents); + submesh.Uvs.swap(uniqueUvs); + submesh.Weights.swap(uniqueWeights); + + // Normalize bone weights + // For example the Blender exporter doesn't care about whether the sum of all bone + // weights for a single vertex equals 1 or not, so validate here. + for(size_t vertexId=0, wlen=submesh.Weights.size(); vertexId<wlen; ++vertexId) { - float WeightSum=0.0f; - for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones - { - WeightSum+=theSubMesh.Weights[VertexId][BoneId].Value; + std::vector<BoneWeight> &weights = submesh.Weights[vertexId]; + + float sum = 0.0f; + for(size_t boneId=0, blen=weights.size(); boneId<blen; ++boneId) { + sum += weights[boneId].Value; } //check if the sum is too far away from 1 - if(WeightSum<1.0f-0.05f || WeightSum>1.0f+0.05f) + if ((sum < (1.0f - 0.05f)) || (sum > (1.0f + 0.05f))) { - //normalize all weights: - for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones - { - theSubMesh.Weights[VertexId][BoneId].Value/=WeightSum; + for(size_t boneId=0, blen=weights.size(); boneId<blen; ++boneId) { + weights[boneId].Value /= sum; } } } - //_________________________________________________________ } - - - -aiMesh* OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vector<Bone>& Bones) const +aiMesh *OgreImporter::CreateAssimpSubMesh(aiScene *pScene, const SubMesh& submesh, const vector<Bone>& bones) const { - const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene - (void)m_CurrentScene; + const size_t sizeVector3D = sizeof(aiVector3D); - aiMesh* NewAiMesh=new aiMesh(); - - //Positions - NewAiMesh->mVertices=new aiVector3D[theSubMesh.Positions.size()]; - memcpy(NewAiMesh->mVertices, &theSubMesh.Positions[0], theSubMesh.Positions.size()*sizeof(aiVector3D)); - NewAiMesh->mNumVertices=theSubMesh.Positions.size(); + aiMesh *dest = new aiMesh(); + + // Material + dest->mMaterialIndex = submesh.MaterialIndex; - //Normals - if(theSubMesh.HasNormals) + // Positions + dest->mVertices = new aiVector3D[submesh.Positions.size()]; + dest->mNumVertices = submesh.Positions.size(); + memcpy(dest->mVertices, &submesh.Positions[0], submesh.Positions.size() * sizeVector3D); + + // Normals + if (submesh.HasNormals) { - NewAiMesh->mNormals=new aiVector3D[theSubMesh.Normals.size()]; - memcpy(NewAiMesh->mNormals, &theSubMesh.Normals[0], theSubMesh.Normals.size()*sizeof(aiVector3D)); + dest->mNormals = new aiVector3D[submesh.Normals.size()]; + memcpy(dest->mNormals, &submesh.Normals[0], submesh.Normals.size() * sizeVector3D); } - - - //until we have support for bitangents, no tangents will be written - /* - //Tangents - if(theSubMesh.HasTangents) + + // Tangents + // Until we have support for bitangents, no tangents will be written + /// @todo Investigate why the above? + if (submesh.HasTangents) { - NewAiMesh->mTangents=new aiVector3D[theSubMesh.Tangents.size()]; - memcpy(NewAiMesh->mTangents, &theSubMesh.Tangents[0], theSubMesh.Tangents.size()*sizeof(aiVector3D)); + DefaultLogger::get()->warn("Tangents found from Ogre mesh but writing to Assimp mesh not yet supported!"); + //dest->mTangents = new aiVector3D[submesh.Tangents.size()]; + //memcpy(dest->mTangents, &submesh.Tangents[0], submesh.Tangents.size() * sizeVector3D); } - */ - //Uvs - if(theSubMesh.Uvs.size()>0) + // UVs + for (size_t i=0, len=submesh.Uvs.size(); i<len; ++i) { - for(unsigned int i=0; i<theSubMesh.Uvs.size(); ++i) - { - NewAiMesh->mNumUVComponents[i]=2; - NewAiMesh->mTextureCoords[i]=new aiVector3D[theSubMesh.Uvs[i].size()]; - memcpy(NewAiMesh->mTextureCoords[i], &(theSubMesh.Uvs[i][0]), theSubMesh.Uvs[i].size()*sizeof(aiVector3D)); - } + dest->mNumUVComponents[i] = 2; + dest->mTextureCoords[i] = new aiVector3D[submesh.Uvs[i].size()]; + memcpy(dest->mTextureCoords[i], &(submesh.Uvs[i][0]), submesh.Uvs[i].size() * sizeVector3D); } - - //---------------------------------------- Bones -------------------------------------------- - - //Copy the weights in in Bone-Vertices Struktur - //(we have them in a Vertex-Bones Structur, this is much easier for making them unique, which is required by assimp - vector< vector<aiVertexWeight> > aiWeights(theSubMesh.BonesUsed);//now the outer list are the bones, and the inner vector the vertices - for(unsigned int VertexId=0; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices + // Bone weights. Convert internal vertex-to-bone mapping to bone-to-vertex. + vector<vector<aiVertexWeight> > assimpWeights(submesh.BonesUsed); + for(size_t vertexId=0, len=submesh.Weights.size(); vertexId<len; ++vertexId) { - for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones + const vector<BoneWeight> &vertexWeights = submesh.Weights[vertexId]; + for (size_t boneId=0, len=vertexWeights.size(); boneId<len; ++boneId) { - aiVertexWeight NewWeight; - NewWeight.mVertexId=VertexId;//the current Vertex, we can't use the Id form the submehs weights, because they are bone id's - NewWeight.mWeight=theSubMesh.Weights[VertexId][BoneId].Value; - aiWeights[theSubMesh.Weights[VertexId][BoneId].BoneId].push_back(NewWeight); + const BoneWeight &ogreWeight = vertexWeights[boneId]; + assimpWeights[ogreWeight.Id].push_back(aiVertexWeight(vertexId, ogreWeight.Value)); } } - + // Bones. + vector<aiBone*> assimpBones; + assimpBones.reserve(submesh.BonesUsed); - vector<aiBone*> aiBones; - aiBones.reserve(theSubMesh.BonesUsed);//the vector might be smaller, because there might be empty bones (bones that are not attached to any vertex) - - //create all the bones and fill them with informations - for(unsigned int i=0; i<theSubMesh.BonesUsed; ++i) + for(size_t boneId=0, len=submesh.BonesUsed; boneId<len; ++boneId) { - if(aiWeights[i].size()>0) - { - aiBone* NewBone=new aiBone(); - NewBone->mNumWeights=aiWeights[i].size(); - NewBone->mWeights=new aiVertexWeight[aiWeights[i].size()]; - memcpy(NewBone->mWeights, &(aiWeights[i][0]), sizeof(aiVertexWeight)*aiWeights[i].size()); - NewBone->mName=Bones[i].Name;//The bone list should be sorted after its id's, this was done in LoadSkeleton - NewBone->mOffsetMatrix=Bones[i].BoneToWorldSpace; - - aiBones.push_back(NewBone); + const vector<aiVertexWeight> &boneWeights = assimpWeights[boneId]; + if (boneWeights.size() == 0) { + continue; } - } - NewAiMesh->mNumBones=aiBones.size(); - - // mBones must be NULL if mNumBones is non 0 or the validation fails. - if (aiBones.size()) { - NewAiMesh->mBones=new aiBone* [aiBones.size()]; - memcpy(NewAiMesh->mBones, &(aiBones[0]), aiBones.size()*sizeof(aiBone*)); + + // @note The bones list is sorted by id's, this was done in LoadSkeleton. + aiBone *assimpBone = new aiBone(); + assimpBone->mName = bones[boneId].Name; + assimpBone->mOffsetMatrix = bones[boneId].BoneToWorldSpace; + assimpBone->mNumWeights = boneWeights.size(); + assimpBone->mWeights = new aiVertexWeight[boneWeights.size()]; + memcpy(assimpBone->mWeights, &boneWeights[0], boneWeights.size() * sizeof(aiVertexWeight)); + + assimpBones.push_back(assimpBone); } - //______________________________________________________________________________________________________ + if (!assimpBones.empty()) + { + dest->mBones = new aiBone*[assimpBones.size()]; + dest->mNumBones = assimpBones.size(); + for(size_t i=0, len=assimpBones.size(); i<len; ++i) { + dest->mBones[i] = assimpBones[i]; + } + } + // Faces + dest->mFaces = new aiFace[submesh.Faces.size()]; + dest->mNumFaces = submesh.Faces.size(); - //Faces - NewAiMesh->mFaces=new aiFace[theSubMesh.FaceList.size()]; - for(unsigned int i=0; i<theSubMesh.FaceList.size(); ++i) + for(size_t i=0, len=submesh.Faces.size(); i<len; ++i) { - NewAiMesh->mFaces[i].mNumIndices=3; - NewAiMesh->mFaces[i].mIndices=new unsigned int[3]; + dest->mFaces[i].mNumIndices = 3; + dest->mFaces[i].mIndices = new unsigned int[3]; - NewAiMesh->mFaces[i].mIndices[0]=theSubMesh.FaceList[i].VertexIndices[0]; - NewAiMesh->mFaces[i].mIndices[1]=theSubMesh.FaceList[i].VertexIndices[1]; - NewAiMesh->mFaces[i].mIndices[2]=theSubMesh.FaceList[i].VertexIndices[2]; + const Face &f = submesh.Faces[i]; + dest->mFaces[i].mIndices[0] = f.VertexIndices[0]; + dest->mFaces[i].mIndices[1] = f.VertexIndices[1]; + dest->mFaces[i].mIndices[2] = f.VertexIndices[2]; } - NewAiMesh->mNumFaces=theSubMesh.FaceList.size(); - - //Link the material: - NewAiMesh->mMaterialIndex=theSubMesh.MaterialIndex;//the index is set by the function who called ReadSubMesh - return NewAiMesh; + return dest; } +} // Ogre +} // Assimp -}//namespace Ogre -}//namespace Assimp - -#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER +#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER diff --git a/src/3rdparty/assimp/code/OgreParsingUtils.h b/src/3rdparty/assimp/code/OgreParsingUtils.h new file mode 100644 index 000000000..ac1e58173 --- /dev/null +++ b/src/3rdparty/assimp/code/OgreParsingUtils.h @@ -0,0 +1,214 @@ + +#ifndef AI_OGREPARSINGUTILS_H_INC +#define AI_OGREPARSINGUTILS_H_INC + +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER + +#include "ParsingUtils.h" +#include "irrXMLWrapper.h" +#include "fast_atof.h" +#include <functional> +namespace Assimp +{ +namespace Ogre +{ + +typedef irr::io::IrrXMLReader XmlReader; + +static void ThrowAttibuteError(const XmlReader* reader, const std::string &name, const std::string &error = "") +{ + if (!error.empty()) + { + throw DeadlyImportError(error + " in node '" + std::string(reader->getNodeName()) + "' and attribute '" + name + "'"); + } + else + { + throw DeadlyImportError("Attribute '" + name + "' does not exist in node '" + std::string(reader->getNodeName()) + "'"); + } +} + +template<typename T> +inline T GetAttribute(const XmlReader* reader, const std::string &name); + +template<> +inline int GetAttribute<int>(const XmlReader* reader, const std::string &name) +{ + const char* value = reader->getAttributeValue(name.c_str()); + if (value) + { + return atoi(value); + } + else + { + ThrowAttibuteError(reader, name); + return 0; + } +} + +template<> +inline unsigned int GetAttribute<unsigned int>(const XmlReader* reader, const std::string &name) +{ + const char* value = reader->getAttributeValue(name.c_str()); + if (value) + { + return static_cast<unsigned int>(atoi(value)); ///< @todo Find a better way... + } + else + { + ThrowAttibuteError(reader, name); + return 0; + } +} + +template<> +inline float GetAttribute<float>(const XmlReader* reader, const std::string &name) +{ + const char* value = reader->getAttributeValue(name.c_str()); + if (value) + { + return fast_atof(value); + } + else + { + ThrowAttibuteError(reader, name); + return 0.f; + } +} + +template<> +inline std::string GetAttribute<std::string>(const XmlReader* reader, const std::string &name) +{ + const char* value = reader->getAttributeValue(name.c_str()); + if (value) + { + return std::string(value); + } + else + { + ThrowAttibuteError(reader, name); + return ""; + } +} + +template<> +inline bool GetAttribute<bool>(const XmlReader* reader, const std::string &name) +{ + std::string value = GetAttribute<std::string>(reader, name); + if (ASSIMP_stricmp(value, "true") == 0) + { + return true; + } + else if (ASSIMP_stricmp(value, "false") == 0) + { + return false; + } + else + { + ThrowAttibuteError(reader, name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'"); + return false; + } +} + +inline bool NextNode(XmlReader* reader) +{ + do + { + if (!reader->read()) { + return false; + } + } + while(reader->getNodeType() != irr::io::EXN_ELEMENT); + return true; +} + +inline bool CurrentNodeNameEquals(const XmlReader* reader, const std::string &name) +{ + return (ASSIMP_stricmp(std::string(reader->getNodeName()), name) == 0); +} + +/// Skips a line from current @ss position until a newline. Returns the skipped part. +static inline std::string SkipLine(std::stringstream &ss) +{ + std::string skipped; + getline(ss, skipped); + return skipped; +} + +/// Skips a line and reads next element from @c ss to @c nextElement. +/** @return Skipped line content until newline. */ +static inline std::string NextAfterNewLine(std::stringstream &ss, std::string &nextElement) +{ + std::string skipped = SkipLine(ss); + ss >> nextElement; + return skipped; +} + +/// Returns a lower cased copy of @s. +static inline std::string ToLower(std::string s) +{ + std::transform(s.begin(), s.end(), s.begin(), ::tolower); + return s; +} + +/// Returns if @c s ends with @c suffix. If @c caseSensitive is false, both strings will be lower cased before matching. +static inline bool EndsWith(const std::string &s, const std::string &suffix, bool caseSensitive = true) +{ + if (s.empty() || suffix.empty()) + { + return false; + } + else if (s.length() < suffix.length()) + { + return false; + } + + if (!caseSensitive) { + return EndsWith(ToLower(s), ToLower(suffix), true); + } + + size_t len = suffix.length(); + std::string sSuffix = s.substr(s.length()-len, len); + return (ASSIMP_stricmp(sSuffix, suffix) == 0); +} + +// Below trim functions adapted from http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring + +/// Trim from start +static inline std::string &TrimLeft(std::string &s, bool newlines = true) +{ + if (!newlines) + { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(Assimp::IsSpace<char>)))); + } + else + { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(Assimp::IsSpaceOrNewLine<char>)))); + } + return s; +} + +/// Trim from end +static inline std::string &TrimRight(std::string &s, bool newlines = true) +{ + if (!newlines) + { + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(Assimp::IsSpace<char>))).base(),s.end()); + } + else + { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(Assimp::IsSpaceOrNewLine<char>)))); + } + return s; +} + +/// Trim from both ends +static inline std::string &Trim(std::string &s, bool newlines = true) +{ + return TrimLeft(TrimRight(s, newlines), newlines); +} + +} // Ogre +} // Assimp + +#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER +#endif // AI_OGREPARSINGUTILS_H_INC diff --git a/src/3rdparty/assimp/code/OgreSkeleton.cpp b/src/3rdparty/assimp/code/OgreSkeleton.cpp index e368142da..4260e3bd9 100644 --- a/src/3rdparty/assimp/code/OgreSkeleton.cpp +++ b/src/3rdparty/assimp/code/OgreSkeleton.cpp @@ -5,11 +5,11 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2012, assimp team All rights reserved. -Redistribution and use of this software in source and binary forms, +Redistribution and use of this software in aSource and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above +* Redistributions of aSource code must retain the above copyright notice, this list of conditions and the following disclaimer. @@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER -#include "OgreImporter.hpp" +#include "OgreImporter.h" #include "TinyFormatter.h" using namespace std; @@ -52,402 +52,395 @@ namespace Assimp namespace Ogre { - - -void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vector<Animation> &Animations) const +void OgreImporter::ReadSkeleton(const std::string &pFile, Assimp::IOSystem *pIOHandler, const aiScene *pScene, + const std::string &skeletonFile, vector<Bone> &Bones, vector<Animation> &Animations) const { - const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene - (void)m_CurrentScene; - - - //most likely the skeleton file will only end with .skeleton - //But this is a xml reader, so we need: .skeleton.xml - FileName+=".xml"; - - DefaultLogger::get()->debug(string("Loading Skeleton: ")+FileName); - - //Open the File: - boost::scoped_ptr<IOStream> File(m_CurrentIOHandler->Open(FileName)); - if(NULL==File.get()) - throw DeadlyImportError("Failed to open skeleton file "+FileName+"."); - - //Read the Mesh File: - boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(File.get())); - XmlReader* SkeletonFile = irr::io::createIrrXMLReader(mIOWrapper.get()); - if(!SkeletonFile) - throw DeadlyImportError(string("Failed to create XML Reader for ")+FileName); + string filename = skeletonFile; + if (EndsWith(filename, ".skeleton")) + { + DefaultLogger::get()->warn("Mesh is referencing a Ogre binary skeleton. Parsing binary Ogre assets is not supported at the moment. Trying to find .skeleton.xml file instead."); + filename += ".xml"; + } - //Quick note: Whoever read this should know this one thing: irrXml fucking sucks!!! + if (!pIOHandler->Exists(filename)) + { + DefaultLogger::get()->error("Failed to find skeleton file '" + filename + "', skeleton will be missing."); + return; + } - XmlRead(SkeletonFile); - if(string("skeleton")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("No <skeleton> node in SkeletonFile: "+FileName); + boost::scoped_ptr<IOStream> file(pIOHandler->Open(filename)); + if (!file.get()) { + throw DeadlyImportError("Failed to open skeleton file " + filename); + } + boost::scoped_ptr<CIrrXML_IOStreamReader> stream(new CIrrXML_IOStreamReader(file.get())); + XmlReader* reader = irr::io::createIrrXMLReader(stream.get()); + if (!reader) { + throw DeadlyImportError("Failed to create XML reader for skeleton file " + filename); + } + DefaultLogger::get()->debug("Reading skeleton '" + filename + "'"); - //------------------------------------load bones----------------------------------------- - XmlRead(SkeletonFile); - if(string("bones")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("No bones node in skeleton "+FileName); + // Root + NextNode(reader); + if (!CurrentNodeNameEquals(reader, "skeleton")) { + throw DeadlyImportError("Root node is not <skeleton> but <" + string(reader->getNodeName()) + "> in " + filename); + } - XmlRead(SkeletonFile); + // Bones + NextNode(reader); + if (!CurrentNodeNameEquals(reader, "bones")) { + throw DeadlyImportError("No <bones> node in skeleton " + skeletonFile); + } - while(string("bone")==SkeletonFile->getNodeName()) + NextNode(reader); + while(CurrentNodeNameEquals(reader, "bone")) { - //TODO: Maybe we can have bone ids for the errrors, but normaly, they should never appear, so what.... + /** @todo Fix this mandatory ordering. Some exporters might just write rotation first etc. + There is no technical reason this has to be so strict. */ - //read a new bone: - Bone NewBone; - NewBone.Id=GetAttribute<int>(SkeletonFile, "id"); - NewBone.Name=GetAttribute<string>(SkeletonFile, "name"); + Bone bone; + bone.Id = GetAttribute<int>(reader, "id"); + bone.Name = GetAttribute<string>(reader, "name"); - //load the position: - XmlRead(SkeletonFile); - if(string("position")!=SkeletonFile->getNodeName()) + NextNode(reader); + if (!CurrentNodeNameEquals(reader, "position")) { throw DeadlyImportError("Position is not first node in Bone!"); - NewBone.Position.x=GetAttribute<float>(SkeletonFile, "x"); - NewBone.Position.y=GetAttribute<float>(SkeletonFile, "y"); - NewBone.Position.z=GetAttribute<float>(SkeletonFile, "z"); + } - //Rotation: - XmlRead(SkeletonFile); - if(string("rotation")!=SkeletonFile->getNodeName()) + bone.Position.x = GetAttribute<float>(reader, "x"); + bone.Position.y = GetAttribute<float>(reader, "y"); + bone.Position.z = GetAttribute<float>(reader, "z"); + + NextNode(reader); + if (!CurrentNodeNameEquals(reader, "rotation")) { throw DeadlyImportError("Rotation is not the second node in Bone!"); - NewBone.RotationAngle=GetAttribute<float>(SkeletonFile, "angle"); - XmlRead(SkeletonFile); - if(string("axis")!=SkeletonFile->getNodeName()) + } + + bone.RotationAngle = GetAttribute<float>(reader, "angle"); + + NextNode(reader); + if (!CurrentNodeNameEquals(reader, "axis")) { throw DeadlyImportError("No axis specified for bone rotation!"); - NewBone.RotationAxis.x=GetAttribute<float>(SkeletonFile, "x"); - NewBone.RotationAxis.y=GetAttribute<float>(SkeletonFile, "y"); - NewBone.RotationAxis.z=GetAttribute<float>(SkeletonFile, "z"); + } + + bone.RotationAxis.x = GetAttribute<float>(reader, "x"); + bone.RotationAxis.y = GetAttribute<float>(reader, "y"); + bone.RotationAxis.z = GetAttribute<float>(reader, "z"); - //append the newly loaded bone to the bone list - Bones.push_back(NewBone); + Bones.push_back(bone); - //Proceed to the next bone: - XmlRead(SkeletonFile); + NextNode(reader); } - //The bones in the file a not neccesarly ordered by there id's so we do it now: + + // Order bones by Id std::sort(Bones.begin(), Bones.end()); - //now the id of each bone should be equal to its position in the vector: - //so we do a simple check: + // Validate that bone indexes are not skipped. + /** @note Left this from original authors code, but not sure if this is strictly necessary + as per the Ogre skeleton spec. It might be more that other (later) code in this imported does not break. */ + for (size_t i=0, len=Bones.size(); i<len; ++i) { - bool IdsOk=true; - for(int i=0; i<static_cast<signed int>(Bones.size()); ++i)//i is signed, because all Id's are also signed! - { - if(Bones[i].Id!=i) - IdsOk=false; + if (static_cast<int>(Bones[i].Id) != static_cast<int>(i)) { + throw DeadlyImportError("Bone Ids are not in sequence in " + skeletonFile); } - if(!IdsOk) - throw DeadlyImportError("Bone Ids are not valid!"+FileName); } - DefaultLogger::get()->debug((Formatter::format(),"Number of bones: ",Bones.size())); - //________________________________________________________________________________ - - - + DefaultLogger::get()->debug(Formatter::format() << " - Bones " << Bones.size()); + // Bone hierarchy + if (!CurrentNodeNameEquals(reader, "bonehierarchy")) { + throw DeadlyImportError("No <bonehierarchy> node found after <bones> in " + skeletonFile); + } - //----------------------------load bonehierarchy-------------------------------- - if(string("bonehierarchy")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("no bonehierarchy node in "+FileName); - - DefaultLogger::get()->debug("loading bonehierarchy..."); - XmlRead(SkeletonFile); - while(string("boneparent")==SkeletonFile->getNodeName()) + NextNode(reader); + while(CurrentNodeNameEquals(reader, "boneparent")) { - string Child, Parent; - Child=GetAttribute<string>(SkeletonFile, "bone"); - Parent=GetAttribute<string>(SkeletonFile, "parent"); - - unsigned int ChildId, ParentId; - ChildId=find(Bones.begin(), Bones.end(), Child)->Id; - ParentId=find(Bones.begin(), Bones.end(), Parent)->Id; + string childName = GetAttribute<string>(reader, "bone"); + string parentName = GetAttribute<string>(reader, "parent"); - Bones[ChildId].ParentId=ParentId; - Bones[ParentId].Children.push_back(ChildId); + vector<Bone>::iterator iterChild = find(Bones.begin(), Bones.end(), childName); + vector<Bone>::iterator iterParent = find(Bones.begin(), Bones.end(), parentName); + + if (iterChild != Bones.end() && iterParent != Bones.end()) + { + iterChild->ParentId = iterParent->Id; + iterParent->Children.push_back(iterChild->Id); + } + else + { + DefaultLogger::get()->warn("Failed to find bones for parenting: Child " + childName + " Parent " + parentName); + } - XmlRead(SkeletonFile);//I once forget this line, which led to an endless loop, did i mentioned, that irrxml sucks?? + NextNode(reader); } - //_____________________________________________________________________________ - - //--------- Calculate the WorldToBoneSpace Matrix recursivly for all bones: ------------------ + // Calculate bone matrices for root bones. Recursively does their children. BOOST_FOREACH(Bone &theBone, Bones) { - if(-1==theBone.ParentId) //the bone is a root bone - { + if (!theBone.IsParented()) { theBone.CalculateBoneToWorldSpaceMatrix(Bones); } } - //_______________________________________________________________________ + aiVector3D zeroVec(0.f, 0.f, 0.f); - //---------------------------load animations----------------------------- - if(string("animations")==SkeletonFile->getNodeName())//animations are optional values + // Animations + if (CurrentNodeNameEquals(reader, "animations")) { - DefaultLogger::get()->debug("Loading Animations"); - XmlRead(SkeletonFile); - while(string("animation")==SkeletonFile->getNodeName()) + DefaultLogger::get()->debug(" - Animations"); + + NextNode(reader); + while(CurrentNodeNameEquals(reader, "animation")) { - Animation NewAnimation; - NewAnimation.Name=GetAttribute<string>(SkeletonFile, "name"); - NewAnimation.Length=GetAttribute<float>(SkeletonFile, "length"); + Animation animation; + animation.Name = GetAttribute<string>(reader, "name"); + animation.Length = GetAttribute<float>(reader, "length"); - //Load all Tracks - XmlRead(SkeletonFile); - if(string("tracks")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("no tracks node in animation"); - XmlRead(SkeletonFile); - while(string("track")==SkeletonFile->getNodeName()) - { - Track NewTrack; - NewTrack.BoneName=GetAttribute<string>(SkeletonFile, "bone"); - - //Load all keyframes; - XmlRead(SkeletonFile); - if(string("keyframes")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("no keyframes node!"); - XmlRead(SkeletonFile); - while(string("keyframe")==SkeletonFile->getNodeName()) - { - Keyframe NewKeyframe; - NewKeyframe.Time=GetAttribute<float>(SkeletonFile, "time"); + // Tracks + NextNode(reader); + if (!CurrentNodeNameEquals(reader, "tracks")) { + throw DeadlyImportError("No <tracks> node found in animation '" + animation.Name + "' in " + skeletonFile); + } - //loop over the attributes: - - while(true) //will quit, if a Node is not a animationkey - { - XmlRead(SkeletonFile); + NextNode(reader); + while(CurrentNodeNameEquals(reader, "track")) + { + Track track; + track.BoneName = GetAttribute<string>(reader, "bone"); - //If any property doesn't show up, it will keep its initialization value + // Keyframes + NextNode(reader); + if (!CurrentNodeNameEquals(reader, "keyframes")) { + throw DeadlyImportError("No <keyframes> node found in a track in animation '" + animation.Name + "' in " + skeletonFile); + } - //Position: - if(string("translate")==SkeletonFile->getNodeName()) + NextNode(reader); + while(CurrentNodeNameEquals(reader, "keyframe")) + { + KeyFrame keyFrame; + keyFrame.Time = GetAttribute<float>(reader, "time"); + + NextNode(reader); + while(CurrentNodeNameEquals(reader, "translate") || CurrentNodeNameEquals(reader, "rotate") || CurrentNodeNameEquals(reader, "scale")) + { + if (CurrentNodeNameEquals(reader, "translate")) { - NewKeyframe.Position.x=GetAttribute<float>(SkeletonFile, "x"); - NewKeyframe.Position.y=GetAttribute<float>(SkeletonFile, "y"); - NewKeyframe.Position.z=GetAttribute<float>(SkeletonFile, "z"); + keyFrame.Position.x = GetAttribute<float>(reader, "x"); + keyFrame.Position.y = GetAttribute<float>(reader, "y"); + keyFrame.Position.z = GetAttribute<float>(reader, "z"); } - - //Rotation: - else if(string("rotate")==SkeletonFile->getNodeName()) + else if (CurrentNodeNameEquals(reader, "rotate")) { - float RotationAngle=GetAttribute<float>(SkeletonFile, "angle"); - aiVector3D RotationAxis; - XmlRead(SkeletonFile); - if(string("axis")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("No axis for keyframe rotation!"); - RotationAxis.x=GetAttribute<float>(SkeletonFile, "x"); - RotationAxis.y=GetAttribute<float>(SkeletonFile, "y"); - RotationAxis.z=GetAttribute<float>(SkeletonFile, "z"); - - if(0==RotationAxis.x && 0==RotationAxis.y && 0==RotationAxis.z)//we have an invalid rotation axis + float angle = GetAttribute<float>(reader, "angle"); + + NextNode(reader); + if (!CurrentNodeNameEquals(reader, "axis")) { + throw DeadlyImportError("No axis for keyframe rotation in animation '" + animation.Name + "'"); + } + + aiVector3D axis; + axis.x = GetAttribute<float>(reader, "x"); + axis.y = GetAttribute<float>(reader, "y"); + axis.z = GetAttribute<float>(reader, "z"); + + if (axis.Equal(zeroVec)) { - RotationAxis.x=1.0f; - if(0!=RotationAngle)//if we don't rotate at all, the axis does not matter - { - DefaultLogger::get()->warn("Invalid Rotation Axis in Keyframe!"); + axis.x = 1.0f; + if (angle != 0) { + DefaultLogger::get()->warn("Found invalid a key frame with a zero rotation axis in animation '" + animation.Name + "'"); } } - NewKeyframe.Rotation=aiQuaternion(RotationAxis, RotationAngle); + keyFrame.Rotation = aiQuaternion(axis, angle); } - - //Scaling: - else if(string("scale")==SkeletonFile->getNodeName()) + else if (CurrentNodeNameEquals(reader, "scale")) { - NewKeyframe.Scaling.x=GetAttribute<float>(SkeletonFile, "x"); - NewKeyframe.Scaling.y=GetAttribute<float>(SkeletonFile, "y"); - NewKeyframe.Scaling.z=GetAttribute<float>(SkeletonFile, "z"); - } - - //we suppose, that we read all attributes and this is a new keyframe or the end of the animation - else - break; + keyFrame.Scaling.x = GetAttribute<float>(reader, "x"); + keyFrame.Scaling.y = GetAttribute<float>(reader, "y"); + keyFrame.Scaling.z = GetAttribute<float>(reader, "z"); + } + NextNode(reader); } - - NewTrack.Keyframes.push_back(NewKeyframe); + track.Keyframes.push_back(keyFrame); } - - NewAnimation.Tracks.push_back(NewTrack); + animation.Tracks.push_back(track); } - - Animations.push_back(NewAnimation); + Animations.push_back(animation); + + DefaultLogger::get()->debug(Formatter::format() << " " << animation.Name << " (" << animation.Length << " sec, " << animation.Tracks.size() << " tracks)"); } } - //_____________________________________________________________________________ - } - -void OgreImporter::CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &/*Animations*/) +void OgreImporter::CreateAssimpSkeleton(aiScene *pScene, const std::vector<Bone> &bones, const std::vector<Animation> &animations) { - if(!m_CurrentScene->mRootNode) - throw DeadlyImportError("No root node exists!!"); - if(0!=m_CurrentScene->mRootNode->mNumChildren) - throw DeadlyImportError("Root Node already has childnodes!"); + if (bones.empty()) { + return; + } + if (!pScene->mRootNode) { + throw DeadlyImportError("Creating Assimp skeleton: No root node created!"); + } + if (pScene->mRootNode->mNumChildren > 0) { + throw DeadlyImportError("Creating Assimp skeleton: Root node already has children!"); + } - //Createt the assimp bone hierarchy - vector<aiNode*> RootBoneNodes; - BOOST_FOREACH(const Bone &theBone, Bones) + // Bones + vector<aiNode*> rootBones; + BOOST_FOREACH(const Bone &bone, bones) { - if(-1==theBone.ParentId) //the bone is a root bone - { - //which will recursily add all other nodes - RootBoneNodes.push_back(CreateAiNodeFromBone(theBone.Id, Bones, m_CurrentScene->mRootNode)); + if (!bone.IsParented()) { + rootBones.push_back(CreateNodeFromBone(bone.Id, bones, pScene->mRootNode)); } } - if(RootBoneNodes.size() > 0) + if (!rootBones.empty()) { - m_CurrentScene->mRootNode->mNumChildren=RootBoneNodes.size(); - m_CurrentScene->mRootNode->mChildren=new aiNode*[RootBoneNodes.size()]; - memcpy(m_CurrentScene->mRootNode->mChildren, &RootBoneNodes[0], sizeof(aiNode*)*RootBoneNodes.size()); - } -} + pScene->mRootNode->mChildren = new aiNode*[rootBones.size()]; + pScene->mRootNode->mNumChildren = rootBones.size(); + for(size_t i=0, len=rootBones.size(); i<len; ++i) { + pScene->mRootNode->mChildren[i] = rootBones[i]; + } + } -void OgreImporter::PutAnimationsInScene(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations) -{ - //-----------------Create the Assimp Animations -------------------- - if(Animations.size()>0)//Maybe the model had only a skeleton and no animations. (If it also has no skeleton, this function would'nt have been called + // TODO: Auf nicht vorhandene Animationskeys achten! + // @todo Pay attention to non-existing animation Keys (google translated from above german comment) + + // Animations + if (!animations.empty()) { - m_CurrentScene->mNumAnimations=Animations.size(); - m_CurrentScene->mAnimations=new aiAnimation*[Animations.size()]; - for(unsigned int i=0; i<Animations.size(); ++i)//create all animations + pScene->mAnimations = new aiAnimation*[animations.size()]; + pScene->mNumAnimations = animations.size(); + + for(size_t ai=0, alen=animations.size(); ai<alen; ++ai) { - aiAnimation* NewAnimation=new aiAnimation(); - NewAnimation->mName=Animations[i].Name; - NewAnimation->mDuration=Animations[i].Length; - NewAnimation->mTicksPerSecond=1.0f; - - //Create all tracks in this animation - NewAnimation->mNumChannels=Animations[i].Tracks.size(); - NewAnimation->mChannels=new aiNodeAnim*[Animations[i].Tracks.size()]; - for(unsigned int j=0; j<Animations[i].Tracks.size(); ++j) + const Animation &aSource = animations[ai]; + + aiAnimation *animation = new aiAnimation(); + animation->mName = aSource.Name; + animation->mDuration = aSource.Length; + animation->mTicksPerSecond = 1.0f; + + // Tracks + animation->mChannels = new aiNodeAnim*[aSource.Tracks.size()]; + animation->mNumChannels = aSource.Tracks.size(); + + for(size_t ti=0, tlen=aSource.Tracks.size(); ti<tlen; ++ti) { - aiNodeAnim* NewNodeAnim=new aiNodeAnim(); - NewNodeAnim->mNodeName=Animations[i].Tracks[j].BoneName; + const Track &tSource = aSource.Tracks[ti]; + + aiNodeAnim *animationNode = new aiNodeAnim(); + animationNode->mNodeName = tSource.BoneName; + + // We need this, to access the bones default pose. + // Which we need to make keys absolute to the default bone pose. + vector<Bone>::const_iterator boneIter = find(bones.begin(), bones.end(), tSource.BoneName); + if (boneIter == bones.end()) + { + for(size_t createdAnimationIndex=0; createdAnimationIndex<ai; createdAnimationIndex++) { + delete pScene->mAnimations[createdAnimationIndex]; + } + delete [] pScene->mAnimations; + pScene->mAnimations = NULL; + pScene->mNumAnimations = 0; + + DefaultLogger::get()->error("Failed to find bone for name " + tSource.BoneName + " when creating animation " + aSource.Name + + ". This is a serious error, animations wont be imported."); + return; + } - //we need this, to acces the bones default pose, which we need to make keys absolute to the default bone pose - vector<Bone>::const_iterator CurBone=find(Bones.begin(), Bones.end(), NewNodeAnim->mNodeName); aiMatrix4x4 t0, t1; - aiMatrix4x4 DefBonePose=aiMatrix4x4::Translation(CurBone->Position, t1) - * aiMatrix4x4::Rotation(CurBone->RotationAngle, CurBone->RotationAxis, t0); - + aiMatrix4x4 defaultBonePose = aiMatrix4x4::Translation(boneIter->Position, t1) * aiMatrix4x4::Rotation(boneIter->RotationAngle, boneIter->RotationAxis, t0); + + // Keyframes + unsigned int numKeyframes = tSource.Keyframes.size(); + + animationNode->mPositionKeys = new aiVectorKey[numKeyframes]; + animationNode->mRotationKeys = new aiQuatKey[numKeyframes]; + animationNode->mScalingKeys = new aiVectorKey[numKeyframes]; + animationNode->mNumPositionKeys = numKeyframes; + animationNode->mNumRotationKeys = numKeyframes; + animationNode->mNumScalingKeys = numKeyframes; - //Create the keyframe arrays... - unsigned int KeyframeCount=Animations[i].Tracks[j].Keyframes.size(); - NewNodeAnim->mNumPositionKeys=KeyframeCount; - NewNodeAnim->mNumRotationKeys=KeyframeCount; - NewNodeAnim->mNumScalingKeys =KeyframeCount; - NewNodeAnim->mPositionKeys=new aiVectorKey[KeyframeCount]; - NewNodeAnim->mRotationKeys=new aiQuatKey[KeyframeCount]; - NewNodeAnim->mScalingKeys =new aiVectorKey[KeyframeCount]; - //...and fill them - for(unsigned int k=0; k<KeyframeCount; ++k) + for(size_t kfi=0; kfi<numKeyframes; ++kfi) { - aiMatrix4x4 t2, t3; - - //Create a matrix to transfrom a vector from the bones default pose to the bone bones in this animation key - aiMatrix4x4 PoseToKey= - aiMatrix4x4::Translation(Animations[i].Tracks[j].Keyframes[k].Position, t3) //pos - * aiMatrix4x4(Animations[i].Tracks[j].Keyframes[k].Rotation.GetMatrix()) //rot - * aiMatrix4x4::Scaling(Animations[i].Tracks[j].Keyframes[k].Scaling, t2); //scale - + const KeyFrame &kfSource = tSource.Keyframes[kfi]; - //calculate the complete transformation from world space to bone space - aiMatrix4x4 CompleteTransform=DefBonePose * PoseToKey; - - aiVector3D Pos; - aiQuaternion Rot; - aiVector3D Scale; + // Create a matrix to transform a vector from the bones + // default pose to the bone bones in this animation key + aiMatrix4x4 t2, t3; + aiMatrix4x4 keyBonePose = + aiMatrix4x4::Translation(kfSource.Position, t3) * + aiMatrix4x4(kfSource.Rotation.GetMatrix()) * + aiMatrix4x4::Scaling(kfSource.Scaling, t2); - CompleteTransform.Decompose(Scale, Rot, Pos); + // Calculate the complete transformation from world space to bone space + aiMatrix4x4 CompleteTransform = defaultBonePose * keyBonePose; - double Time=Animations[i].Tracks[j].Keyframes[k].Time; + aiVector3D kfPos; aiQuaternion kfRot; aiVector3D kfScale; + CompleteTransform.Decompose(kfScale, kfRot, kfPos); - NewNodeAnim->mPositionKeys[k].mTime=Time; - NewNodeAnim->mPositionKeys[k].mValue=Pos; - - NewNodeAnim->mRotationKeys[k].mTime=Time; - NewNodeAnim->mRotationKeys[k].mValue=Rot; + animationNode->mPositionKeys[kfi].mTime = static_cast<double>(kfSource.Time); + animationNode->mRotationKeys[kfi].mTime = static_cast<double>(kfSource.Time); + animationNode->mScalingKeys[kfi].mTime = static_cast<double>(kfSource.Time); - NewNodeAnim->mScalingKeys[k].mTime=Time; - NewNodeAnim->mScalingKeys[k].mValue=Scale; + animationNode->mPositionKeys[kfi].mValue = kfPos; + animationNode->mRotationKeys[kfi].mValue = kfRot; + animationNode->mScalingKeys[kfi].mValue = kfScale; } - - NewAnimation->mChannels[j]=NewNodeAnim; + animation->mChannels[ti] = animationNode; } - - m_CurrentScene->mAnimations[i]=NewAnimation; + pScene->mAnimations[ai] = animation; } } -//TODO: Auf nicht vorhandene Animationskeys achten! -//#pragma warning (s.o.) - //__________________________________________________________________ } - -aiNode* OgreImporter::CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode) +aiNode* OgreImporter::CreateNodeFromBone(int boneId, const std::vector<Bone> &bones, aiNode* parent) { - //----Create the node for this bone and set its values----- - aiNode* NewNode=new aiNode(Bones[BoneId].Name); - NewNode->mParent=ParentNode; - aiMatrix4x4 t0,t1; - NewNode->mTransformation= - aiMatrix4x4::Translation(Bones[BoneId].Position, t0) - *aiMatrix4x4::Rotation(Bones[BoneId].RotationAngle, Bones[BoneId].RotationAxis, t1) - ; - //__________________________________________________________ + const Bone &source = bones[boneId]; + aiNode* boneNode = new aiNode(source.Name); + boneNode->mParent = parent; + boneNode->mTransformation = aiMatrix4x4::Translation(source.Position, t0) * aiMatrix4x4::Rotation(source.RotationAngle, source.RotationAxis, t1); - //---------- recursivly create all children Nodes: ---------- - NewNode->mNumChildren=Bones[BoneId].Children.size(); - NewNode->mChildren=new aiNode*[Bones[BoneId].Children.size()]; - for(unsigned int i=0; i<Bones[BoneId].Children.size(); ++i) + if (!source.Children.empty()) { - NewNode->mChildren[i]=CreateAiNodeFromBone(Bones[BoneId].Children[i], Bones, NewNode); - } - //____________________________________________________ + boneNode->mChildren = new aiNode*[source.Children.size()]; + boneNode->mNumChildren = source.Children.size(); + for(size_t i=0, len=source.Children.size(); i<len; ++i) { + boneNode->mChildren[i] = CreateNodeFromBone(source.Children[i], bones, boneNode); + } + } - return NewNode; + return boneNode; } - void Bone::CalculateBoneToWorldSpaceMatrix(vector<Bone> &Bones) { - //Calculate the matrix for this bone: - - aiMatrix4x4 t0,t1; - aiMatrix4x4 Transf= aiMatrix4x4::Rotation(-RotationAngle, RotationAxis, t1) - * aiMatrix4x4::Translation(-Position, t0); + aiMatrix4x4 t0, t1; + aiMatrix4x4 transform = aiMatrix4x4::Rotation(-RotationAngle, RotationAxis, t1) * aiMatrix4x4::Translation(-Position, t0); - if(-1==ParentId) + if (!IsParented()) { - BoneToWorldSpace=Transf; + BoneToWorldSpace = transform; } else { - BoneToWorldSpace=Transf*Bones[ParentId].BoneToWorldSpace; + BoneToWorldSpace = transform * Bones[ParentId].BoneToWorldSpace; } - - //and recursivly for all children: - BOOST_FOREACH(int theChildren, Children) + // Recursively for all children now that the parent matrix has been calculated. + BOOST_FOREACH(int childId, Children) { - Bones[theChildren].CalculateBoneToWorldSpaceMatrix(Bones); + Bones[childId].CalculateBoneToWorldSpaceMatrix(Bones); } } +} // Ogre +} // Assimp -}//namespace Ogre -}//namespace Assimp - -#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER +#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER diff --git a/src/3rdparty/assimp/code/OptimizeMeshes.cpp b/src/3rdparty/assimp/code/OptimizeMeshes.cpp index d93216fea..dce0ebddc 100644 --- a/src/3rdparty/assimp/code/OptimizeMeshes.cpp +++ b/src/3rdparty/assimp/code/OptimizeMeshes.cpp @@ -74,7 +74,7 @@ bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const // That's a serious design flaw, consider redesign. if( 0 != (pFlags & aiProcess_OptimizeMeshes) ) { pts = (0 != (pFlags & aiProcess_SortByPType)); - max_verts = (0 != (pFlags & aiProcess_SplitLargeMeshes)) ? 0xdeadbeef : 0; + max_verts = (0 != (pFlags & aiProcess_SplitLargeMeshes)) ? 0xdeadbeef : max_verts; return true; } return false; diff --git a/src/3rdparty/assimp/code/ParsingUtils.h b/src/3rdparty/assimp/code/ParsingUtils.h index 6032c10ab..0c34e70ca 100644 --- a/src/3rdparty/assimp/code/ParsingUtils.h +++ b/src/3rdparty/assimp/code/ParsingUtils.h @@ -115,7 +115,7 @@ AI_FORCE_INLINE bool SkipSpaces( const char_t** inout) } // --------------------------------------------------------------------------------- template <class char_t> -inline bool SkipLine( const char_t* in, const char_t** out) +AI_FORCE_INLINE bool SkipLine( const char_t* in, const char_t** out) { while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++; @@ -126,13 +126,13 @@ inline bool SkipLine( const char_t* in, const char_t** out) } // --------------------------------------------------------------------------------- template <class char_t> -inline bool SkipLine( const char_t** inout) +AI_FORCE_INLINE bool SkipLine( const char_t** inout) { return SkipLine<char_t>(*inout,inout); } // --------------------------------------------------------------------------------- template <class char_t> -inline bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) +AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) { while (*in == (char_t)' ' || *in == (char_t)'\t' || *in == (char_t)'\r' || *in == (char_t)'\n')in++; @@ -141,13 +141,13 @@ inline bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) } // --------------------------------------------------------------------------------- template <class char_t> -inline bool SkipSpacesAndLineEnd( const char_t** inout) +AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout) { return SkipSpacesAndLineEnd<char_t>(*inout,inout); } // --------------------------------------------------------------------------------- template <class char_t> -inline bool GetNextLine(const char_t*& buffer, char_t out[4096]) +AI_FORCE_INLINE bool GetNextLine(const char_t*& buffer, char_t out[4096]) { if ((char_t)'\0' == *buffer)return false; diff --git a/src/3rdparty/assimp/code/PlyExporter.cpp b/src/3rdparty/assimp/code/PlyExporter.cpp index beaabeb1f..b2e0b352a 100644 --- a/src/3rdparty/assimp/code/PlyExporter.cpp +++ b/src/3rdparty/assimp/code/PlyExporter.cpp @@ -57,6 +57,10 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene // we're still here - export successfully completed. Write the file. boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output .ply file: " + std::string(pFile)); + } + outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1); } @@ -99,7 +103,7 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene) mOutput << "ply" << endl; mOutput << "format ascii 1.0" << endl; - mOutput << "Created by Open Asset Import Library - http://assimp.sf.net (v" + mOutput << "comment Created by Open Asset Import Library - http://assimp.sf.net (v" << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.' << aiGetVersionRevision() << ")" << endl; @@ -155,7 +159,7 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene) } mOutput << "element face " << faces << endl; - mOutput << "property list uint uint vertex_indices" << endl; + mOutput << "property list uint uint vertex_index" << endl; mOutput << "end_header" << endl; for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { diff --git a/src/3rdparty/assimp/code/PlyParser.cpp b/src/3rdparty/assimp/code/PlyParser.cpp index 90b216d75..048fd5e99 100644 --- a/src/3rdparty/assimp/code/PlyParser.cpp +++ b/src/3rdparty/assimp/code/PlyParser.cpp @@ -427,7 +427,7 @@ bool PLY::DOM::SkipComments (const char* pCur, } // ------------------------------------------------------------------------------------------------ -bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut) +bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut,bool isBinary) { ai_assert(NULL != pCur && NULL != pCurOut); DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin"); @@ -458,7 +458,10 @@ bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut) SkipLine(&pCur); } } - SkipSpacesAndLineEnd(pCur,&pCur); + if(!isBinary) + { // it would occur an error, if binary data start with values as space or line end. + SkipSpacesAndLineEnd(pCur,&pCur); + } *pCurOut = pCur; DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded"); @@ -527,7 +530,7 @@ bool PLY::DOM::ParseInstanceBinary (const char* pCur,DOM* p_pcOut,bool p_bBE) DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin"); - if(!p_pcOut->ParseHeader(pCur,&pCur)) + if(!p_pcOut->ParseHeader(pCur,&pCur,true)) { DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure"); return false; @@ -550,7 +553,7 @@ bool PLY::DOM::ParseInstance (const char* pCur,DOM* p_pcOut) DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin"); - if(!p_pcOut->ParseHeader(pCur,&pCur)) + if(!p_pcOut->ParseHeader(pCur,&pCur,false)) { DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure"); return false; diff --git a/src/3rdparty/assimp/code/PlyParser.h b/src/3rdparty/assimp/code/PlyParser.h index d8083a625..9120c20b0 100644 --- a/src/3rdparty/assimp/code/PlyParser.h +++ b/src/3rdparty/assimp/code/PlyParser.h @@ -434,7 +434,7 @@ private: // ------------------------------------------------------------------- //! Handle the file header and read all element descriptions - bool ParseHeader (const char* pCur,const char** pCurOut); + bool ParseHeader (const char* pCur,const char** pCurOut, bool p_bBE); // ------------------------------------------------------------------- //! Read in all element instance lists diff --git a/src/3rdparty/assimp/code/PostStepRegistry.cpp b/src/3rdparty/assimp/code/PostStepRegistry.cpp index 5229fd628..579b48c13 100644 --- a/src/3rdparty/assimp/code/PostStepRegistry.cpp +++ b/src/3rdparty/assimp/code/PostStepRegistry.cpp @@ -47,6 +47,7 @@ corresponding preprocessor flag to selectively disable steps. */ #include "AssimpPCH.h" +#include "ProcessHelper.h" #ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS # include "CalcTangentsProcess.h" @@ -132,6 +133,15 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) // validated - as RegisterPPStep() does - all dependencies must be given. // ---------------------------------------------------------------------------- out.reserve(25); +#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS) + out.push_back( new MakeLeftHandedProcess()); +#endif +#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS) + out.push_back( new FlipUVsProcess()); +#endif +#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS) + out.push_back( new FlipWindingOrderProcess()); +#endif #if (!defined ASSIMP_BUILD_NO_REMOVEVC_PROCESS) out.push_back( new RemoveVCProcess()); #endif @@ -144,9 +154,6 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) #if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS) out.push_back( new OptimizeGraphProcess()); #endif -#if (!defined ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS) - out.push_back( new OptimizeMeshesProcess()); -#endif #if (!defined ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS) out.push_back( new FindDegeneratesProcess()); #endif @@ -168,6 +175,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) #if (!defined ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS) out.push_back( new FindInvalidDataProcess()); #endif +#if (!defined ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS) + out.push_back( new OptimizeMeshesProcess()); +#endif #if (!defined ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS) out.push_back( new FixInfacingNormalsProcess()); #endif @@ -206,16 +216,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) #if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS) out.push_back( new SplitLargeMeshesProcess_Vertex()); #endif -#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS) - out.push_back( new MakeLeftHandedProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS) - out.push_back( new FlipUVsProcess()); -#endif -#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS) - out.push_back( new FlipWindingOrderProcess()); -#endif -#if (!defined ASSIMP_BUILD_DEBONE_PROCESS) +#if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS) out.push_back( new DeboneProcess()); #endif #if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS) diff --git a/src/3rdparty/assimp/code/PretransformVertices.cpp b/src/3rdparty/assimp/code/PretransformVertices.cpp index 2877dde0d..2b0304578 100644 --- a/src/3rdparty/assimp/code/PretransformVertices.cpp +++ b/src/3rdparty/assimp/code/PretransformVertices.cpp @@ -57,7 +57,7 @@ using namespace Assimp; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer PretransformVertices::PretransformVertices() -: configKeepHierarchy (false) +: configKeepHierarchy (false), configNormalize(false), configTransform(false), configTransformation() { } @@ -79,9 +79,13 @@ bool PretransformVertices::IsActive( unsigned int pFlags) const // Setup import configuration void PretransformVertices::SetupProperties(const Importer* pImp) { - // Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY and AI_CONFIG_PP_PTV_NORMALIZE + // Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY, AI_CONFIG_PP_PTV_NORMALIZE, + // AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION and AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,0)); configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE,0)); + configTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION,0)); + + configTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4()); } // ------------------------------------------------------------------------------------------------ @@ -391,6 +395,8 @@ void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in ntz->mBones = reinterpret_cast<aiBone**> (&node->mTransformation); out.push_back(ntz); + + node->mMeshes[i] = numIn + out.size() - 1; } } } @@ -437,6 +443,10 @@ void PretransformVertices::Execute( aiScene* pScene) const unsigned int iOldAnimationChannels = pScene->mNumAnimations; const unsigned int iOldNodes = CountNodes(pScene->mRootNode); + if(configTransform) { + pScene->mRootNode->mTransformation = configTransformation; + } + // first compute absolute transformation matrices for all nodes ComputeAbsoluteTransform(pScene->mRootNode); diff --git a/src/3rdparty/assimp/code/PretransformVertices.h b/src/3rdparty/assimp/code/PretransformVertices.h index 8836fdd0b..3738810ff 100644 --- a/src/3rdparty/assimp/code/PretransformVertices.h +++ b/src/3rdparty/assimp/code/PretransformVertices.h @@ -52,11 +52,11 @@ class PretransformVerticesTest; namespace Assimp { // --------------------------------------------------------------------------- -/** The PretransformVertices pretransforms all vertices in the nodegraph +/** The PretransformVertices pre-transforms all vertices in the node tree * and removes the whole graph. The output is a list of meshes, one for * each material. */ -class PretransformVertices : public BaseProcess +class ASSIMP_API PretransformVertices : public BaseProcess { public: @@ -152,8 +152,10 @@ private: //! Configuration option: keep scene hierarchy as long as possible - bool configKeepHierarchy, configNormalize; - + bool configKeepHierarchy; + bool configNormalize; + bool configTransform; + aiMatrix4x4 configTransformation; }; } // end of namespace Assimp diff --git a/src/3rdparty/assimp/code/Q3BSPFileData.h b/src/3rdparty/assimp/code/Q3BSPFileData.h index 0e74b9573..a3516ae36 100644 --- a/src/3rdparty/assimp/code/Q3BSPFileData.h +++ b/src/3rdparty/assimp/code/Q3BSPFileData.h @@ -42,10 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <vector> -namespace Assimp -{ -namespace Q3BSP -{ +namespace Assimp { +namespace Q3BSP { static const unsigned int CE_BSP_LIGHTMAPWIDTH = 128; static const unsigned int CE_BSP_LIGHTMAPHEIGHT = 128; @@ -54,8 +52,7 @@ static const unsigned int CE_BSP_LIGHTMAPSIZE = 128*128*3; ///< = 128( width ) * static const int VERION_Q3LEVEL = 46; ///< Supported version. /// Geometric type enumeration -enum Q3BSPGeoType -{ +enum Q3BSPGeoType { Polygon = 1, Patch, TriangleMesh, @@ -63,25 +60,23 @@ enum Q3BSPGeoType }; /// Integer vector. -struct ceVec3i -{ +struct ceVec3i { int x, y, z; ceVec3i(): x( 0 ), y( 0 ), z( 0 ) { /* empty */ } ceVec3i( int iX, int iY=0, int iZ=0) : x( iX ), y( iY ), z( iZ ) { /* empty */ } }; -/// Fileheader -struct sQ3BSPHeader -{ - char strID[ 4 ]; //!< Should be "IBSP" - int iVersion; //!< 46 for standard levels +/// the file header +struct sQ3BSPHeader { + char strID[ 4 ]; ///< Should be "IBSP" + int iVersion; ///< 46 for standard levels }; -/// Descripes an entry. +/// Describes an entry. struct sQ3BSPLump { - int iOffset; ///< Offset from startpointer of file - int iSize; ///< Size fo part + int iOffset; ///< Offset from start pointer of file + int iSize; ///< Size of part }; struct vec2f @@ -108,47 +103,42 @@ struct sQ3BSPVertex struct sQ3BSPFace { int iTextureID; ///< Index in texture array - int iEffect; ///< Index in effectarray (-1 = no effect) + int iEffect; ///< Index in effect array (-1 = no effect) int iType; ///< 1=Polygon, 2=Patch, 3=Mesh, 4=Billboard int iVertexIndex; ///< Start index of polygon int iNumOfVerts; ///< Number of vertices int iFaceVertexIndex; ///< Index of first mesh vertex - int iNumOfFaceVerts; ///< Anzahl der Meshvertices - int iLightmapID; ///< Index to the lightmap array - int iLMapCorner[ 2 ]; ///< Die Ecke der Lightmap in der Textur - int iLMapSize[ 2 ]; ///< Size of the lightmap stored on the texture - vec3f vLMapPos; ///< 3D-Ursprung der Lightmap - vec3f vLMapVecs[ 2 ]; ///< 3D-s-t-Vektoren - vec3f vNormal; ///< Polygonnormale + int iNumOfFaceVerts; ///< number of mesh vertices + int iLightmapID; ///< Index to the light-map array + int iLMapCorner[ 2 ]; ///< edge of the light-map in texture + int iLMapSize[ 2 ]; ///< Size of the light-map stored on the texture + vec3f vLMapPos; ///< 3D origin of the light-map + vec3f vLMapVecs[ 2 ]; ///< 3D-s-t-vectors + vec3f vNormal; ///< Polygon normals int patchWidth, patchHeight; ///< bezier patch }; /// A quake3 texture name. -struct sQ3BSPTexture -{ - char strName[ 64 ]; ///< Name of the texture without extention +struct sQ3BSPTexture { + char strName[ 64 ]; ///< Name of the texture without extension int iFlags; ///< Not used int iContents; ///< Not used }; -/// A lightmap of the level, size 128 x 128, RGB components. -struct sQ3BSPLightmap -{ +/// A light-map of the level, size 128 x 128, RGB components. +struct sQ3BSPLightmap { unsigned char bLMapData[ CE_BSP_LIGHTMAPSIZE ]; - sQ3BSPLightmap() - { - memset(bLMapData, 0, CE_BSP_LIGHTMAPSIZE ); + sQ3BSPLightmap() { + ::memset(bLMapData, 0, CE_BSP_LIGHTMAPSIZE ); } }; -struct SubPatch -{ +struct SubPatch { std::vector<size_t> indices; int lightmapID; }; -enum eLumps -{ +enum eLumps { kEntities = 0, kTextures, kPlanes, @@ -169,8 +159,7 @@ enum eLumps kMaxLumps }; -struct Q3BSPModel -{ +struct Q3BSPModel { std::vector<unsigned char> m_Data; std::vector<sQ3BSPLump*> m_Lumps; std::vector<sQ3BSPVertex*> m_Vertices; @@ -195,24 +184,22 @@ struct Q3BSPModel // empty } - ~Q3BSPModel() - { - for ( unsigned int i=0; i<m_Lumps.size(); i++ ) - if ( NULL != m_Lumps[i] ) - delete m_Lumps[i]; - - for ( unsigned int i=0; i<m_Vertices.size(); i++ ) - if ( NULL != m_Vertices[ i ] ) - delete m_Vertices[ i ]; - for ( unsigned int i=0; i<m_Faces.size(); i++ ) - if ( NULL != m_Faces[ i ] ) - delete m_Faces[ i ]; - for ( unsigned int i=0; i<m_Textures.size(); i++ ) - if ( NULL != m_Textures[ i ] ) - delete m_Textures[ i ]; - for ( unsigned int i=0; i<m_Lightmaps.size(); i++ ) - if ( NULL != m_Lightmaps[ i ] ) - delete m_Lightmaps[ i ]; + ~Q3BSPModel() { + for ( unsigned int i=0; i<m_Lumps.size(); i++ ) { + delete m_Lumps[ i ]; + } + for ( unsigned int i=0; i<m_Vertices.size(); i++ ) { + delete m_Vertices[ i ]; + } + for ( unsigned int i=0; i<m_Faces.size(); i++ ) { + delete m_Faces[ i ]; + } + for ( unsigned int i=0; i<m_Textures.size(); i++ ) { + delete m_Textures[ i ]; + } + for ( unsigned int i=0; i<m_Lightmaps.size(); i++ ) { + delete m_Lightmaps[ i ]; + } m_Lumps.clear(); m_Vertices.clear(); diff --git a/src/3rdparty/assimp/code/Q3BSPFileImporter.cpp b/src/3rdparty/assimp/code/Q3BSPFileImporter.cpp index 44d8d7b11..81a770261 100644 --- a/src/3rdparty/assimp/code/Q3BSPFileImporter.cpp +++ b/src/3rdparty/assimp/code/Q3BSPFileImporter.cpp @@ -71,9 +71,14 @@ static const aiImporterDesc desc = { "pk3" }; -namespace Assimp -{ +namespace Assimp { +static void getSupportedExtensions(std::vector<std::string> &supportedExtensions) { + supportedExtensions.push_back( ".jpg" ); + supportedExtensions.push_back( ".png" ); + supportedExtensions.push_back( ".tga" ); +} + using namespace Q3BSP; // ------------------------------------------------------------------------------------------------ @@ -86,7 +91,7 @@ static void createKey( int id1, int id2, std::string &rKey ) } // ------------------------------------------------------------------------------------------------ -// Local function to extract the texture ids from a material keyname. +// Local function to extract the texture ids from a material key-name. static void extractIds( const std::string &rKey, int &rId1, int &rId2 ) { rId1 = -1; @@ -146,24 +151,16 @@ Q3BSPFileImporter::Q3BSPFileImporter() : // ------------------------------------------------------------------------------------------------ // Destructor. -Q3BSPFileImporter::~Q3BSPFileImporter() -{ - // For lint +Q3BSPFileImporter::~Q3BSPFileImporter() { m_pCurrentMesh = NULL; m_pCurrentFace = NULL; // Clear face-to-material map - for ( FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); - ++it ) - { - const std::string matName = (*it).first; - if ( matName.empty() ) - { - continue; + for ( FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it ) { + const std::string &matName = it->first; + if ( !matName.empty() ) { + delete it->second; } - - std::vector<Q3BSP::sQ3BSPFace*> *pCurFaceArray = (*it).second; - delete pCurFaceArray; } m_MaterialLookupMap.clear(); } @@ -188,9 +185,9 @@ const aiImporterDesc* Q3BSPFileImporter::GetInfo () const // ------------------------------------------------------------------------------------------------ // Import method. -void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* /*pIOHandler*/) +void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* pIOHandler) { - Q3BSPZipArchive Archive( rFile ); + Q3BSPZipArchive Archive( pIOHandler, rFile ); if ( !Archive.isOpen() ) { throw DeadlyImportError( "Failed to open file " + rFile + "." ); @@ -566,7 +563,7 @@ size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rAr } // ------------------------------------------------------------------------------------------------ -// Counts the number of triangles in a Q3-facearray. +// Counts the number of triangles in a Q3-face-array. size_t Q3BSPFileImporter::countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const { size_t numTriangles = 0; @@ -617,16 +614,11 @@ void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel ) // Returns the next face. aiFace *Q3BSPFileImporter::getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx ) { - aiFace *pFace = NULL; - if ( rFaceIdx < pMesh->mNumFaces ) - { + aiFace *pFace( NULL ); + if ( rFaceIdx < pMesh->mNumFaces ) { pFace = &pMesh->mFaces[ rFaceIdx ]; rFaceIdx++; } - else - { - pFace = NULL; - } return pFace; } @@ -634,33 +626,30 @@ aiFace *Q3BSPFileImporter::getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx ) // ------------------------------------------------------------------------------------------------ // Imports a texture file. bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel, - Q3BSP::Q3BSPZipArchive *pArchive, aiScene* /*pScene*/, - aiMaterial *pMatHelper, int textureId ) -{ - std::vector<std::string> supportedExtensions; - supportedExtensions.push_back( ".jpg" ); - supportedExtensions.push_back( ".png" ); - if ( NULL == pArchive || NULL == pArchive || NULL == pMatHelper ) - { + Q3BSP::Q3BSPZipArchive *pArchive, aiScene*, + aiMaterial *pMatHelper, int textureId ) { + if ( NULL == pArchive || NULL == pArchive || NULL == pMatHelper ) { return false; } - if ( textureId < 0 || textureId >= static_cast<int>( pModel->m_Textures.size() ) ) - { + if ( textureId < 0 || textureId >= static_cast<int>( pModel->m_Textures.size() ) ) { return false; } bool res = true; sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ]; - if ( NULL == pTexture ) - return false; - + if ( !pTexture ) { + return false; + } + + std::vector<std::string> supportedExtensions; + supportedExtensions.push_back( ".jpg" ); + supportedExtensions.push_back( ".png" ); + supportedExtensions.push_back( ".tga" ); std::string textureName, ext; - if ( expandFile( pArchive, pTexture->strName, supportedExtensions, textureName, ext ) ) - { + if ( expandFile( pArchive, pTexture->strName, supportedExtensions, textureName, ext ) ) { IOStream *pTextureStream = pArchive->Open( textureName.c_str() ); - if ( NULL != pTextureStream ) - { + if ( !pTextureStream ) { size_t texSize = pTextureStream->FileSize(); aiTexture *pTexture = new aiTexture; pTexture->mHeight = 0; @@ -670,10 +659,10 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode (void)readSize; ai_assert( readSize == pTexture->mWidth ); pTexture->pcData = reinterpret_cast<aiTexel*>( pData ); - pTexture->achFormatHint[ 0 ] = ext[ 0 ]; - pTexture->achFormatHint[ 1 ] = ext[ 1 ]; - pTexture->achFormatHint[ 2 ] = ext[ 2 ]; - pTexture->achFormatHint[ 2 ] = '\0'; + pTexture->achFormatHint[ 0 ] = ext[ 1 ]; + pTexture->achFormatHint[ 1 ] = ext[ 2 ]; + pTexture->achFormatHint[ 2 ] = ext[ 3 ]; + pTexture->achFormatHint[ 3 ] = '\0'; res = true; aiString name; @@ -684,9 +673,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); mTextures.push_back( pTexture ); - } - else - { + } else { // If it doesn't exist in the archive, it is probably just a reference to an external file. // We'll leave it up to the user to figure out which extension the file has. aiString name; diff --git a/src/3rdparty/assimp/code/Q3BSPFileParser.cpp b/src/3rdparty/assimp/code/Q3BSPFileParser.cpp index e6135df30..9713798f7 100644 --- a/src/3rdparty/assimp/code/Q3BSPFileParser.cpp +++ b/src/3rdparty/assimp/code/Q3BSPFileParser.cpp @@ -38,6 +38,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ #include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER + #include "Q3BSPFileParser.h" #include "DefaultIOSystem.h" #include "Q3BSPFileData.h" @@ -273,3 +276,5 @@ void Q3BSPFileParser::getEntities() // ------------------------------------------------------------------------------------------------ } // Namespace Assimp + +#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER diff --git a/src/3rdparty/assimp/code/Q3BSPZipArchive.cpp b/src/3rdparty/assimp/code/Q3BSPZipArchive.cpp index 3039a1496..ec98a2877 100644 --- a/src/3rdparty/assimp/code/Q3BSPZipArchive.cpp +++ b/src/3rdparty/assimp/code/Q3BSPZipArchive.cpp @@ -39,27 +39,151 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER + #include "Q3BSPZipArchive.h" #include <algorithm> #include <cassert> -namespace Assimp -{ -namespace Q3BSP -{ +namespace Assimp { +namespace Q3BSP { + +voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) { + IOSystem* io_system = (IOSystem*) opaque; + + const char* mode_fopen = NULL; + if((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) { + mode_fopen = "rb"; + } else { + if(mode & ZLIB_FILEFUNC_MODE_EXISTING) { + mode_fopen = "r+b"; + } else { + if(mode & ZLIB_FILEFUNC_MODE_CREATE) { + mode_fopen = "wb"; + } + } + } + + return (voidpf) io_system->Open(filename, mode_fopen); +} + +uLong IOSystem2Unzip::read(voidpf opaque, voidpf stream, void* buf, uLong size) { + IOStream* io_stream = (IOStream*) stream; + + return io_stream->Read(buf, 1, size); +} + +uLong IOSystem2Unzip::write(voidpf opaque, voidpf stream, const void* buf, uLong size) { + IOStream* io_stream = (IOStream*) stream; + + return io_stream->Write(buf, 1, size); +} + +long IOSystem2Unzip::tell(voidpf opaque, voidpf stream) { + IOStream* io_stream = (IOStream*) stream; + + return io_stream->Tell(); +} + +long IOSystem2Unzip::seek(voidpf opaque, voidpf stream, uLong offset, int origin) { + IOStream* io_stream = (IOStream*) stream; + + aiOrigin assimp_origin; + switch (origin) { + default: + case ZLIB_FILEFUNC_SEEK_CUR: + assimp_origin = aiOrigin_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END: + assimp_origin = aiOrigin_END; + break; + case ZLIB_FILEFUNC_SEEK_SET: + assimp_origin = aiOrigin_SET; + break; + } + + return (io_stream->Seek(offset, assimp_origin) == aiReturn_SUCCESS ? 0 : -1); +} + +int IOSystem2Unzip::close(voidpf opaque, voidpf stream) { + IOSystem* io_system = (IOSystem*) opaque; + IOStream* io_stream = (IOStream*) stream; + + io_system->Close(io_stream); + + return 0; +} + +int IOSystem2Unzip::testerror(voidpf opaque, voidpf stream) { + return 0; +} + +zlib_filefunc_def IOSystem2Unzip::get(IOSystem* pIOHandler) { + zlib_filefunc_def mapping; + + mapping.zopen_file = open; + mapping.zread_file = read; + mapping.zwrite_file = write; + mapping.ztell_file = tell; + mapping.zseek_file = seek; + mapping.zclose_file = close; + mapping.zerror_file = testerror; + mapping.opaque = (voidpf) pIOHandler; + + return mapping; +} + +// ------------------------------------------------------------------------------------------------ +ZipFile::ZipFile(size_t size) : m_Size(size) { + ai_assert(m_Size != 0); + + m_Buffer = std::malloc(m_Size); +} + +ZipFile::~ZipFile() { + std::free(m_Buffer); + m_Buffer = NULL; +} + +size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) { + const size_t size = pSize * pCount; + assert(size <= m_Size); + + std::memcpy(pvBuffer, m_Buffer, size); + + return size; +} + +size_t ZipFile::Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { + return 0; +} + +size_t ZipFile::FileSize() const { + return m_Size; +} + +aiReturn ZipFile::Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { + return aiReturn_FAILURE; +} + +size_t ZipFile::Tell() const { + return 0; +} + +void ZipFile::Flush() { + // empty +} // ------------------------------------------------------------------------------------------------ // Constructor. -Q3BSPZipArchive::Q3BSPZipArchive( const std::string& rFile ) : - m_ZipFileHandle( NULL ), - m_FileList(), - m_bDirty( true ) -{ - if ( !rFile.empty() ) - { - m_ZipFileHandle = unzOpen( rFile.c_str() ); - if ( NULL != m_ZipFileHandle ) - { +Q3BSPZipArchive::Q3BSPZipArchive(IOSystem* pIOHandler, const std::string& rFile) : m_ZipFileHandle(NULL), m_ArchiveMap() { + if (! rFile.empty()) { + zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler); + + m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping); + + if(m_ZipFileHandle != NULL) { mapArchive(); } } @@ -67,130 +191,127 @@ Q3BSPZipArchive::Q3BSPZipArchive( const std::string& rFile ) : // ------------------------------------------------------------------------------------------------ // Destructor. -Q3BSPZipArchive::~Q3BSPZipArchive() -{ - if ( NULL != m_ZipFileHandle ) - { - unzClose( m_ZipFileHandle ); +Q3BSPZipArchive::~Q3BSPZipArchive() { + for( std::map<std::string, ZipFile*>::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it ) { + delete it->second; + } + m_ArchiveMap.clear(); + + if(m_ZipFileHandle != NULL) { + unzClose(m_ZipFileHandle); + m_ZipFileHandle = NULL; } - m_ZipFileHandle = NULL; - m_FileList.clear(); } // ------------------------------------------------------------------------------------------------ // Returns true, if the archive is already open. -bool Q3BSPZipArchive::isOpen() const -{ - return ( NULL != m_ZipFileHandle ); +bool Q3BSPZipArchive::isOpen() const { + return (m_ZipFileHandle != NULL); } // ------------------------------------------------------------------------------------------------ // Returns true, if the filename is part of the archive. -bool Q3BSPZipArchive::Exists( const char* pFile ) const -{ - ai_assert( NULL != pFile ); - if ( NULL == pFile ) - { - return false; - } +bool Q3BSPZipArchive::Exists(const char* pFile) const { + ai_assert(pFile != NULL); + + bool exist = false; + + if (pFile != NULL) { + std::string rFile(pFile); + std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile); - std::string rFile( pFile ); - std::vector<std::string>::const_iterator it = std::find( m_FileList.begin(), m_FileList.end(), rFile ); - if ( m_FileList.end() == it ) - { - return false; + if(it != m_ArchiveMap.end()) { + exist = true; + } } - return true; + return exist; } // ------------------------------------------------------------------------------------------------ // Returns the separator delimiter. -char Q3BSPZipArchive::getOsSeparator() const -{ +char Q3BSPZipArchive::getOsSeparator() const { +#ifndef _WIN32 return '/'; +#else + return '\\'; +#endif } // ------------------------------------------------------------------------------------------------ // Opens a file, which is part of the archive. -IOStream *Q3BSPZipArchive::Open( const char* pFile, const char* /*pMode*/ ) -{ - ai_assert( NULL != pFile ); +IOStream *Q3BSPZipArchive::Open(const char* pFile, const char* /*pMode*/) { + ai_assert(pFile != NULL); + + IOStream* result = NULL; - std::string rItem( pFile ); - std::vector<std::string>::iterator it = std::find( m_FileList.begin(), m_FileList.end(), rItem ); - if ( m_FileList.end() == it ) - return NULL; + std::map<std::string, ZipFile*>::iterator it = m_ArchiveMap.find(pFile); - ZipFile *pZipFile = new ZipFile( *it, m_ZipFileHandle ); - m_ArchiveMap[ rItem ] = pZipFile; + if(it != m_ArchiveMap.end()) { + result = (IOStream*) it->second; + } - return pZipFile; + return result; } // ------------------------------------------------------------------------------------------------ // Close a filestream. -void Q3BSPZipArchive::Close( IOStream *pFile ) -{ - ai_assert( NULL != pFile ); - - std::map<std::string, IOStream*>::iterator it; - for ( it = m_ArchiveMap.begin(); it != m_ArchiveMap.end(); ++it ) - { - if ( (*it).second == pFile ) - { - ZipFile *pZipFile = reinterpret_cast<ZipFile*>( (*it).second ); - delete pZipFile; - m_ArchiveMap.erase( it ); - break; - } - } +void Q3BSPZipArchive::Close(IOStream *pFile) { + ai_assert(pFile != NULL); + + // We don't do anything in case the file would be opened again in the future } // ------------------------------------------------------------------------------------------------ // Returns the file-list of the archive. -void Q3BSPZipArchive::getFileList( std::vector<std::string> &rFileList ) -{ - rFileList = m_FileList; +void Q3BSPZipArchive::getFileList(std::vector<std::string> &rFileList) { + rFileList.clear(); + + for(std::map<std::string, ZipFile*>::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it) { + rFileList.push_back(it->first); + } } // ------------------------------------------------------------------------------------------------ // Maps the archive content. -bool Q3BSPZipArchive::mapArchive() -{ - if ( NULL == m_ZipFileHandle ) - return false; - - if ( !m_bDirty ) - return true; - - if ( !m_FileList.empty() ) - m_FileList.resize( 0 ); - - // At first ensure file is already open - if ( UNZ_OK == unzGoToFirstFile( m_ZipFileHandle ) ) - { - char filename[ FileNameSize ]; - unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 ); - m_FileList.push_back( filename ); - unzCloseCurrentFile( m_ZipFileHandle ); - - // Loop over all files - while ( unzGoToNextFile( m_ZipFileHandle ) != UNZ_END_OF_LIST_OF_FILE ) - { - char filename[ FileNameSize ]; - unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 ); - m_FileList.push_back( filename ); - unzCloseCurrentFile( m_ZipFileHandle ); +bool Q3BSPZipArchive::mapArchive() { + bool success = false; + + if(m_ZipFileHandle != NULL) { + if(m_ArchiveMap.empty()) { + // At first ensure file is already open + if(unzGoToFirstFile(m_ZipFileHandle) == UNZ_OK) { + // Loop over all files + do { + char filename[FileNameSize]; + unz_file_info fileInfo; + + if(unzGetCurrentFileInfo(m_ZipFileHandle, &fileInfo, filename, FileNameSize, NULL, 0, NULL, 0) == UNZ_OK) { + // The file has EXACTLY the size of uncompressed_size. In C + // you need to mark the last character with '\0', so add + // another character + if(unzOpenCurrentFile(m_ZipFileHandle) == UNZ_OK) { + std::pair<std::map<std::string, ZipFile*>::iterator, bool> result = m_ArchiveMap.insert(std::make_pair(filename, new ZipFile(fileInfo.uncompressed_size))); + + if(unzReadCurrentFile(m_ZipFileHandle, result.first->second->m_Buffer, fileInfo.uncompressed_size) == (long int) fileInfo.uncompressed_size) { + if(unzCloseCurrentFile(m_ZipFileHandle) == UNZ_OK) { + // Nothing to do anymore... + } + } + } + } + } while(unzGoToNextFile(m_ZipFileHandle) != UNZ_END_OF_LIST_OF_FILE); + } } + + success = true; } - - std::sort( m_FileList.begin(), m_FileList.end() ); - m_bDirty = false; - return true; + return success; } // ------------------------------------------------------------------------------------------------ } // Namespace Q3BSP } // Namespace Assimp + +#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER diff --git a/src/3rdparty/assimp/code/Q3BSPZipArchive.h b/src/3rdparty/assimp/code/Q3BSPZipArchive.h index 8ddafd49d..12ce6a52d 100644 --- a/src/3rdparty/assimp/code/Q3BSPZipArchive.h +++ b/src/3rdparty/assimp/code/Q3BSPZipArchive.h @@ -48,10 +48,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <map> #include <cassert> -namespace Assimp -{ -namespace Q3BSP -{ +namespace Assimp { +namespace Q3BSP { + +// ------------------------------------------------------------------------------------------------ +/// \class IOSystem2Unzip +/// \ingroup Assimp::Q3BSP +/// +/// \brief +// ------------------------------------------------------------------------------------------------ +class IOSystem2Unzip { + + public: + + static voidpf open(voidpf opaque, const char* filename, int mode); + + static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size); + + static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size); + + static long tell(voidpf opaque, voidpf stream); + + static long seek(voidpf opaque, voidpf stream, uLong offset, int origin); + + static int close(voidpf opaque, voidpf stream); + + static int testerror(voidpf opaque, voidpf stream); + + static zlib_filefunc_def get(IOSystem* pIOHandler); +}; // ------------------------------------------------------------------------------------------------ /// \class ZipFile @@ -59,88 +84,33 @@ namespace Q3BSP /// /// \brief // ------------------------------------------------------------------------------------------------ -class ZipFile : public IOStream -{ -public: - ZipFile( const std::string &rFileName, unzFile zipFile ) : - m_Name( rFileName ), - m_zipFile( zipFile ) - { - ai_assert( NULL != m_zipFile ); - } +class ZipFile : public IOStream { + + friend class Q3BSPZipArchive; + + public: + + ZipFile(size_t size); - ~ZipFile() - { - m_zipFile = NULL; - } - - size_t Read(void* pvBuffer, size_t pSize, size_t pCount ) - { - size_t bytes_read = 0; - if ( NULL == m_zipFile ) - return bytes_read; - - // search file and place file pointer there - if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK ) - { - // get file size, etc. - unz_file_info fileInfo; - unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 ); - const size_t size = pSize * pCount; - assert( size <= fileInfo.uncompressed_size ); - - // The file has EXACTLY the size of uncompressed_size. In C - // you need to mark the last character with '\0', so add - // another character - unzOpenCurrentFile( m_zipFile ); - const int ret = unzReadCurrentFile( m_zipFile, pvBuffer, fileInfo.uncompressed_size); - size_t filesize = fileInfo.uncompressed_size; - if ( ret < 0 || size_t(ret) != filesize ) - { - return 0; - } - bytes_read = ret; - unzCloseCurrentFile( m_zipFile ); - } - return bytes_read; - } - - size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) - { - return 0; - } - - size_t FileSize() const - { - if ( NULL == m_zipFile ) - return 0; - if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK ) - { - unz_file_info fileInfo; - unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 ); - return fileInfo.uncompressed_size; - } - return 0; - } - - aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) - { - return aiReturn_FAILURE; - } - - size_t Tell() const - { - return 0; - } - - void Flush() - { - // empty - } - -private: - std::string m_Name; - unzFile m_zipFile; + ~ZipFile(); + + size_t Read(void* pvBuffer, size_t pSize, size_t pCount ); + + size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/); + + size_t FileSize() const; + + aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/); + + size_t Tell() const; + + void Flush(); + + private: + + void* m_Buffer; + + size_t m_Size; }; // ------------------------------------------------------------------------------------------------ @@ -150,29 +120,40 @@ private: /// \brief IMplements a zip archive like the WinZip archives. Will be also used to import data /// from a P3K archive ( Quake level format ). // ------------------------------------------------------------------------------------------------ -class Q3BSPZipArchive : public Assimp::IOSystem -{ -public: - static const unsigned int FileNameSize = 256; - -public: - Q3BSPZipArchive( const std::string & rFile ); - ~Q3BSPZipArchive(); - bool Exists( const char* pFile) const; - char getOsSeparator() const; - IOStream* Open(const char* pFile, const char* pMode = "rb"); - void Close( IOStream* pFile); - bool isOpen() const; - void getFileList( std::vector<std::string> &rFileList ); - -private: - bool mapArchive(); - -private: - unzFile m_ZipFileHandle; - std::map<std::string, IOStream*> m_ArchiveMap; - std::vector<std::string> m_FileList; - bool m_bDirty; +class Q3BSPZipArchive : public Assimp::IOSystem { + + public: + + static const unsigned int FileNameSize = 256; + + public: + + Q3BSPZipArchive(IOSystem* pIOHandler, const std::string & rFile); + + ~Q3BSPZipArchive(); + + bool Exists(const char* pFile) const; + + char getOsSeparator() const; + + IOStream* Open(const char* pFile, const char* pMode = "rb"); + + void Close(IOStream* pFile); + + bool isOpen() const; + + void getFileList(std::vector<std::string> &rFileList); + + private: + + bool mapArchive(); + + private: + + unzFile m_ZipFileHandle; + + std::map<std::string, ZipFile*> m_ArchiveMap; + }; // ------------------------------------------------------------------------------------------------ diff --git a/src/3rdparty/assimp/code/Q3DLoader.cpp b/src/3rdparty/assimp/code/Q3DLoader.cpp index e53fbe97e..54b545604 100644 --- a/src/3rdparty/assimp/code/Q3DLoader.cpp +++ b/src/3rdparty/assimp/code/Q3DLoader.cpp @@ -379,8 +379,7 @@ void Q3DImporter::InternReadFile( const std::string& pFile, light->mColorSpecular = light->mColorDiffuse; - // We don't need the rest, but we need to know where - // this fucking chunk ends. + // We don't need the rest, but we need to know where this chunk ends. unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4()); // skip the background file name diff --git a/src/3rdparty/assimp/code/RemoveComments.h b/src/3rdparty/assimp/code/RemoveComments.h index acc8db751..8b162584e 100644 --- a/src/3rdparty/assimp/code/RemoveComments.h +++ b/src/3rdparty/assimp/code/RemoveComments.h @@ -55,7 +55,7 @@ namespace Assimp { * to those in C or C++ so this code has been moved to a separate * module. */ -class CommentRemover +class ASSIMP_API CommentRemover { // class cannot be instanced CommentRemover() {} diff --git a/src/3rdparty/assimp/code/RemoveRedundantMaterials.cpp b/src/3rdparty/assimp/code/RemoveRedundantMaterials.cpp index 39643d318..9a93f150c 100644 --- a/src/3rdparty/assimp/code/RemoveRedundantMaterials.cpp +++ b/src/3rdparty/assimp/code/RemoveRedundantMaterials.cpp @@ -86,7 +86,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) { DefaultLogger::get()->debug("RemoveRedundantMatsProcess begin"); - unsigned int iCnt = 0, unreferenced = 0; + unsigned int redundantRemoved = 0, unreferencedRemoved = 0; if (pScene->mNumMaterials) { // Find out which materials are referenced by meshes @@ -125,9 +125,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) } } - // TODO: reimplement this algorithm to work in-place - unsigned int* aiMappingTable = new unsigned int[pScene->mNumMaterials]; unsigned int iNewNum = 0; @@ -139,36 +137,42 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) aiHashes = new uint32_t[pScene->mNumMaterials]; for (unsigned int i = 0; i < pScene->mNumMaterials;++i) { - // if the material is not referenced ... remove it - if (!abReferenced[i]) { - ++unreferenced; + // No mesh is referencing this material, remove it. + if (!abReferenced[i]) { + ++unreferencedRemoved; + delete pScene->mMaterials[i]; continue; } + // Check all previously mapped materials for a matching hash. + // On a match we can delete this material and just make it ref to the same index. uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]); for (unsigned int a = 0; a < i;++a) { if (abReferenced[a] && me == aiHashes[a]) { - ++iCnt; + ++redundantRemoved; me = 0; aiMappingTable[i] = aiMappingTable[a]; delete pScene->mMaterials[i]; break; } } + // This is a new material that is referenced, add to the map. if (me) { aiMappingTable[i] = iNewNum++; } } - if (iCnt) { - // build an output material list + // If the new material count differs from the original, + // we need to rebuild the material list and remap mesh material indexes. + if (iNewNum != pScene->mNumMaterials) { aiMaterial** ppcMaterials = new aiMaterial*[iNewNum]; ::memset(ppcMaterials,0,sizeof(void*)*iNewNum); for (unsigned int p = 0; p < pScene->mNumMaterials;++p) { // if the material is not referenced ... remove it - if (!abReferenced[p]) + if (!abReferenced[p]) { continue; + } // generate new names for all modified materials const unsigned int idx = aiMappingTable[p]; @@ -178,10 +182,11 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) sz.length = ::sprintf(sz.data,"JoinedMaterial_#%i",p); ((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME); } - else ppcMaterials[idx] = pScene->mMaterials[p]; + else + ppcMaterials[idx] = pScene->mMaterials[p]; } // update all material indices - for (unsigned int p = 0; p < pScene->mNumMeshes;++p) { + for (unsigned int p = 0; p < pScene->mNumMeshes;++p) { aiMesh* mesh = pScene->mMeshes[p]; mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex]; } @@ -194,12 +199,15 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene) delete[] aiHashes; delete[] aiMappingTable; } - if (!iCnt)DefaultLogger::get()->debug("RemoveRedundantMatsProcess finished "); + if (redundantRemoved == 0 && unreferencedRemoved == 0) + { + DefaultLogger::get()->debug("RemoveRedundantMatsProcess finished "); + } else { char szBuffer[128]; // should be sufficiently large - ::sprintf(szBuffer,"RemoveRedundantMatsProcess finished. %i redundant and %i unused materials", - iCnt,unreferenced); + ::sprintf(szBuffer,"RemoveRedundantMatsProcess finished. Removed %i redundant and %i unused materials.", + redundantRemoved,unreferencedRemoved); DefaultLogger::get()->info(szBuffer); } } diff --git a/src/3rdparty/assimp/code/RemoveRedundantMaterials.h b/src/3rdparty/assimp/code/RemoveRedundantMaterials.h index da824c06e..a10634d55 100644 --- a/src/3rdparty/assimp/code/RemoveRedundantMaterials.h +++ b/src/3rdparty/assimp/code/RemoveRedundantMaterials.h @@ -51,14 +51,16 @@ class RemoveRedundantMatsTest; namespace Assimp { // --------------------------------------------------------------------------- -/** RemoveRedundantMatsProcess: Postprocessing steo to remove redundant +/** RemoveRedundantMatsProcess: Post-processing step to remove redundant * materials from the imported scene. */ -class RemoveRedundantMatsProcess : public BaseProcess +class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess { public: - + /// The default class constructor. RemoveRedundantMatsProcess(); + + /// The class destructor. ~RemoveRedundantMatsProcess(); public: diff --git a/src/3rdparty/assimp/code/RemoveVCProcess.h b/src/3rdparty/assimp/code/RemoveVCProcess.h index aaae25f84..e9f6be21b 100644 --- a/src/3rdparty/assimp/code/RemoveVCProcess.h +++ b/src/3rdparty/assimp/code/RemoveVCProcess.h @@ -46,17 +46,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../include/assimp/mesh.h" class RemoveVCProcessTest; -namespace Assimp { + +namespace Assimp { // --------------------------------------------------------------------------- /** RemoveVCProcess: Class to exclude specific parts of the data structure * from further processing by removing them, */ -class RemoveVCProcess : public BaseProcess +class ASSIMP_API RemoveVCProcess : public BaseProcess { public: - + /// The default class constructor. RemoveVCProcess(); + + /// The class destructor. ~RemoveVCProcess(); public: @@ -85,7 +88,7 @@ public: // ------------------------------------------------------------------- /** Manually setup the configuration flags for the step * - * @param Bitwise combintion of the #aiComponent enumerated values. + * @param Bitwise combination of the #aiComponent enumerated values. */ void SetDeleteFlags(unsigned int f) { @@ -113,6 +116,8 @@ private: aiScene* mScene; }; +// --------------------------------------------------------------------------- + } // end of namespace Assimp #endif // !!AI_REMOVEVCPROCESS_H_INCLUDED diff --git a/src/3rdparty/assimp/code/SMDLoader.cpp b/src/3rdparty/assimp/code/SMDLoader.cpp index 79e8d4007..4717e5f15 100644 --- a/src/3rdparty/assimp/code/SMDLoader.cpp +++ b/src/3rdparty/assimp/code/SMDLoader.cpp @@ -684,7 +684,7 @@ void SMDImporter::ParseFile() const char* szCurrent = mBuffer; // read line per line ... - while (true) + for ( ;; ) { if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break; @@ -750,7 +750,7 @@ unsigned int SMDImporter::GetTextureIndex(const std::string& filename) void SMDImporter::ParseNodesSection(const char* szCurrent, const char** szCurrentOut) { - while (true) + for ( ;; ) { // "end\n" - Ends the nodes section if (0 == ASSIMP_strincmp(szCurrent,"end",3) && @@ -772,7 +772,7 @@ void SMDImporter::ParseTrianglesSection(const char* szCurrent, { // Parse a triangle, parse another triangle, parse the next triangle ... // and so on until we reach a token that looks quite similar to "end" - while (true) + for ( ;; ) { if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break; @@ -790,7 +790,7 @@ void SMDImporter::ParseVASection(const char* szCurrent, const char** szCurrentOut) { unsigned int iCurIndex = 0; - while (true) + for ( ;; ) { if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break; @@ -833,7 +833,7 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent, const char** szCurrentOut) { int iTime = 0; - while (true) + for ( ;; ) { if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break; @@ -887,7 +887,7 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent, else ++szCurrent; const char* szEnd = szCurrent; - while (true) + for ( ;; ) { if (bQuota && '\"' == *szEnd) { diff --git a/src/3rdparty/assimp/code/STEPFile.h b/src/3rdparty/assimp/code/STEPFile.h index 2e0f20b83..b06554e76 100644 --- a/src/3rdparty/assimp/code/STEPFile.h +++ b/src/3rdparty/assimp/code/STEPFile.h @@ -195,13 +195,13 @@ namespace STEP { // conversion support. template <typename T> const T& ResolveSelect(const DB& db) const { - return Couple<T>(db).MustGetObject(To<EXPRESS::ENTITY>())->template To<T>(); + return Couple<T>(db).MustGetObject(To<EXPRESS::ENTITY>())->template To<T>(); } template <typename T> const T* ResolveSelectPtr(const DB& db) const { const EXPRESS::ENTITY* e = ToPtr<EXPRESS::ENTITY>(); - return e?Couple<T>(db).MustGetObject(*e)->template ToPtr<T>():(const T*)0; + return e?Couple<T>(db).MustGetObject(*e)->template ToPtr<T>():(const T*)0; } public: diff --git a/src/3rdparty/assimp/code/STEPFileEncoding.cpp b/src/3rdparty/assimp/code/STEPFileEncoding.cpp new file mode 100644 index 000000000..e56a1ba42 --- /dev/null +++ b/src/3rdparty/assimp/code/STEPFileEncoding.cpp @@ -0,0 +1,433 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file STEPFileEncoding.cpp + * @brief STEP character handling, string unescaping + */ +#include "AssimpPCH.h" +#include "STEPFileEncoding.h" +#include "fast_atof.h" + +#include "../contrib/ConvertUTF/ConvertUTF.h" + +using namespace Assimp; + +// roman1 to utf16 table +static const UTF16 mac_codetable[] = { + // 0x20 unassig./nonprint. slots + 0x0020 , + 0x0021 , + 0x0022 , + 0x0023 , + 0x0024 , + 0x0025 , + 0x0026 , + 0x0027 , + 0x0028 , + 0x0029 , + 0x002A , + 0x002B , + 0x002C , + 0x002D , + 0x002E , + 0x002F , + 0x0030 , + 0x0031 , + 0x0032 , + 0x0033 , + 0x0034 , + 0x0035 , + 0x0036 , + 0x0037 , + 0x0038 , + 0x0039 , + 0x003A , + 0x003B , + 0x003C , + 0x003D , + 0x003E , + 0x003F , + 0x0040 , + 0x0041 , + 0x0042 , + 0x0043 , + 0x0044 , + 0x0045 , + 0x0046 , + 0x0047 , + 0x0048 , + 0x0049 , + 0x004A , + 0x004B , + 0x004C , + 0x004D , + 0x004E , + 0x004F , + 0x0050 , + 0x0051 , + 0x0052 , + 0x0053 , + 0x0054 , + 0x0055 , + 0x0056 , + 0x0057 , + 0x0058 , + 0x0059 , + 0x005A , + 0x005B , + 0x005C , + 0x005D , + 0x005E , + 0x005F , + 0x0060 , + 0x0061 , + 0x0062 , + 0x0063 , + 0x0064 , + 0x0065 , + 0x0066 , + 0x0067 , + 0x0068 , + 0x0069 , + 0x006A , + 0x006B , + 0x006C , + 0x006D , + 0x006E , + 0x006F , + 0x0070 , + 0x0071 , + 0x0072 , + 0x0073 , + 0x0074 , + 0x0075 , + 0x0076 , + 0x0077 , + 0x0078 , + 0x0079 , + 0x007A , + 0x007B , + 0x007C , + 0x007D , + 0x007E , + 0x0000 , // unassig. + 0x00C4 , + 0x00C5 , + 0x00C7 , + 0x00C9 , + 0x00D1 , + 0x00D6 , + 0x00DC , + 0x00E1 , + 0x00E0 , + 0x00E2 , + 0x00E4 , + 0x00E3 , + 0x00E5 , + 0x00E7 , + 0x00E9 , + 0x00E8 , + 0x00EA , + 0x00EB , + 0x00ED , + 0x00EC , + 0x00EE , + 0x00EF , + 0x00F1 , + 0x00F3 , + 0x00F2 , + 0x00F4 , + 0x00F6 , + 0x00F5 , + 0x00FA , + 0x00F9 , + 0x00FB , + 0x00FC , + 0x2020 , + 0x00B0 , + 0x00A2 , + 0x00A3 , + 0x00A7 , + 0x2022 , + 0x00B6 , + 0x00DF , + 0x00AE , + 0x00A9 , + 0x2122 , + 0x00B4 , + 0x00A8 , + 0x2260 , + 0x00C6 , + 0x00D8 , + 0x221E , + 0x00B1 , + 0x2264 , + 0x2265 , + 0x00A5 , + 0x00B5 , + 0x2202 , + 0x2211 , + 0x220F , + 0x03C0 , + 0x222B , + 0x00AA , + 0x00BA , + 0x03A9 , + 0x00E6 , + 0x00F8 , + 0x00BF , + 0x00A1 , + 0x00AC , + 0x221A , + 0x0192 , + 0x2248 , + 0x2206 , + 0x00AB , + 0x00BB , + 0x2026 , + 0x00A0 , + 0x00C0 , + 0x00C3 , + 0x00D5 , + 0x0152 , + 0x0153 , + 0x2013 , + 0x2014 , + 0x201C , + 0x201D , + 0x2018 , + 0x2019 , + 0x00F7 , + 0x25CA , + 0x00FF , + 0x0178 , + 0x2044 , + 0x20AC , + 0x2039 , + 0x203A , + 0xFB01 , + 0xFB02 , + 0x2021 , + 0x00B7 , + 0x201A , + 0x201E , + 0x2030 , + 0x00C2 , + 0x00CA , + 0x00C1 , + 0x00CB , + 0x00C8 , + 0x00CD , + 0x00CE , + 0x00CF , + 0x00CC , + 0x00D3 , + 0x00D4 , + 0xF8FF , + 0x00D2 , + 0x00DA , + 0x00DB , + 0x00D9 , + 0x0131 , + 0x02C6 , + 0x02DC , + 0x00AF , + 0x02D8 , + 0x02D9 , + 0x02DA , + 0x00B8 , + 0x02DD , + 0x02DB , + 0x02C7 +}; + +// ------------------------------------------------------------------------------------------------ +bool STEP::StringToUTF8(std::string& s) +{ + // very basic handling for escaped string sequences + // http://doc.spatial.com/index.php?title=InterOp:Connect/STEP&redirect=no + + for (size_t i = 0; i < s.size(); ) { + if (s[i] == '\\') { + // \S\X - cp1252 (X is the character remapped to [0,127]) + if (i+3 < s.size() && s[i+1] == 'S' && s[i+2] == '\\') { + // http://stackoverflow.com/questions/5586214/how-to-convert-char-from-iso-8859-1-to-utf-8-in-c-multiplatformly + ai_assert((uint8_t)s[i+3] < 0x80); + const uint8_t ch = s[i+3] + 0x80; + + s[i] = 0xc0 | (ch & 0xc0) >> 6; + s[i+1] = 0x80 | (ch & 0x3f); + + s.erase(i + 2,2); + ++i; + } + // \X\xx - mac/roman (xx is a hex sequence) + else if (i+4 < s.size() && s[i+1] == 'X' && s[i+2] == '\\') { + + const uint8_t macval = HexOctetToDecimal(s.c_str() + i + 3); + if(macval < 0x20) { + return false; + } + + ai_assert(sizeof(mac_codetable) / sizeof(mac_codetable[0]) == 0x100-0x20); + + const UTF32 unival = mac_codetable[macval - 0x20], *univalp = &unival; + + UTF8 temp[5], *tempp = temp; + ai_assert(sizeof(UTF8) == 1); + + if(ConvertUTF32toUTF8(&univalp, univalp+1, &tempp, tempp+sizeof(temp), lenientConversion) != conversionOK) { + return false; + } + + const size_t outcount = static_cast<size_t>(tempp-temp); + + s.erase(i,5); + s.insert(i, reinterpret_cast<char*>(temp), outcount); + i += outcount; + } + // \Xn\ .. \X0\ - various unicode encodings (n=2: utf16; n=4: utf32) + else if (i+3 < s.size() && s[i+1] == 'X' && s[i+2] >= '0' && s[i+2] <= '9') { + switch(s[i+2]) { + // utf16 + case '2': + // utf32 + case '4': + if (s[i+3] == '\\') { + const size_t basei = i+4; + size_t j = basei, jend = s.size()-4; + + for (; j < jend; ++j) { + if (s[j] == '\\' && s[j] == 'X' && s[j] == '0' && s[j] == '\\') { + break; + } + } + if (j == jend) { + return false; + } + + if (j == basei) { + s.erase(i,8); + continue; + } + + if (s[i+2] == '2') { + if (((j - basei) % 4) != 0) { + return false; + } + + const size_t count = (j-basei)/4; + boost::scoped_array<UTF16> src(new UTF16[count]); + + const char* cur = s.c_str() + basei; + for (size_t k = 0; k < count; ++k, cur += 4) { + src[k] = (static_cast<UTF16>(HexOctetToDecimal(cur)) << 8u) | + static_cast<UTF16>(HexOctetToDecimal(cur+2)); + } + + const size_t dcount = count * 3; // this is enough to hold all possible outputs + boost::scoped_array<UTF8> dest(new UTF8[dcount]); + + const UTF16* srct = src.get(); + UTF8* destt = dest.get(); + if(ConvertUTF16toUTF8(&srct, srct+count, &destt, destt+dcount, lenientConversion) != conversionOK) { + return false; + } + + const size_t outcount = static_cast<size_t>(destt-dest.get()); + + s.erase(i,(j+4-i)); + + ai_assert(sizeof(UTF8) == 1); + s.insert(i, reinterpret_cast<char*>(dest.get()), outcount); + + i += outcount; + continue; + } + else if (s[i+2] == '4') { + if (((j - basei) % 8) != 0) { + return false; + } + + const size_t count = (j-basei)/8; + boost::scoped_array<UTF32> src(new UTF32[count]); + + const char* cur = s.c_str() + basei; + for (size_t k = 0; k < count; ++k, cur += 8) { + src[k] = (static_cast<UTF32>(HexOctetToDecimal(cur )) << 24u) | + (static_cast<UTF32>(HexOctetToDecimal(cur+2)) << 16u) | + (static_cast<UTF32>(HexOctetToDecimal(cur+4)) << 8u) | + (static_cast<UTF32>(HexOctetToDecimal(cur+6))); + } + + const size_t dcount = count * 5; // this is enough to hold all possible outputs + boost::scoped_array<UTF8> dest(new UTF8[dcount]); + + const UTF32* srct = src.get(); + UTF8* destt = dest.get(); + if(ConvertUTF32toUTF8(&srct, srct+count, &destt, destt+dcount, lenientConversion) != conversionOK) { + return false; + } + + const size_t outcount = static_cast<size_t>(destt-dest.get()); + + s.erase(i,(j+4-i)); + + ai_assert(sizeof(UTF8) == 1); + s.insert(i, reinterpret_cast<char*>(dest.get()), outcount); + + i += outcount; + continue; + } + } + + break; + + // TODO: other encoding patterns? + + default: + return false; + } + } + } + ++i; + } + return true; +} diff --git a/src/3rdparty/assimp/code/STEPFileEncoding.h b/src/3rdparty/assimp/code/STEPFileEncoding.h new file mode 100644 index 000000000..64b7652f3 --- /dev/null +++ b/src/3rdparty/assimp/code/STEPFileEncoding.h @@ -0,0 +1,63 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef INCLUDED_AI_STEPFILEENCODING_H +#define INCLUDED_AI_STEPFILEENCODING_H + +#include <string> + +namespace Assimp { +namespace STEP { + + + // -------------------------------------------------------------------------- + // Convert an ASCII STEP identifier with possibly escaped character + // sequences using foreign encodings to plain UTF8. + // + // Return false if an error occurs, s may or may not be modified in + // this case and could still contain escape sequences (even partly + // escaped ones). + bool StringToUTF8(std::string& s); + + +} // ! STEP +} // ! Assimp + +#endif diff --git a/src/3rdparty/assimp/code/STEPFileReader.cpp b/src/3rdparty/assimp/code/STEPFileReader.cpp index 6961ef633..c9561daa9 100644 --- a/src/3rdparty/assimp/code/STEPFileReader.cpp +++ b/src/3rdparty/assimp/code/STEPFileReader.cpp @@ -44,9 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "AssimpPCH.h" #include "STEPFileReader.h" +#include "STEPFileEncoding.h" #include "TinyFormatter.h" #include "fast_atof.h" + using namespace Assimp; namespace EXPRESS = STEP::EXPRESS; @@ -160,6 +162,30 @@ STEP::DB* STEP::ReadFileHeader(boost::shared_ptr<IOStream> stream) } +namespace { + +// ------------------------------------------------------------------------------------------------ +// check whether the given line contains an entity definition (i.e. starts with "#<number>=") +bool IsEntityDef(const std::string& snext) +{ + if (snext[0] == '#') { + // it is only a new entity if it has a '=' after the + // entity ID. + for(std::string::const_iterator it = snext.begin()+1; it != snext.end(); ++it) { + if (*it == '=') { + return true; + } + if ((*it < '0' || *it > '9') && *it != ' ') { + break; + } + } + } + return false; +} + +} + + // ------------------------------------------------------------------------------------------------ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const* types_to_track, size_t len, @@ -171,49 +197,94 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const DB::ObjectMap& map = db.GetObjects(); LineSplitter& splitter = db.GetSplitter(); - for(; splitter; ++splitter) { - const std::string& s = *splitter; + + while (splitter) { + bool has_next = false; + std::string s = *splitter; if (s == "ENDSEC;") { break; } + s.erase(std::remove(s.begin(), s.end(), ' '), s.end()); // want one-based line numbers for human readers, so +1 const uint64_t line = splitter.get_index()+1; - // LineSplitter already ignores empty lines ai_assert(s.length()); if (s[0] != '#') { DefaultLogger::get()->warn(AddLineNumber("expected token \'#\'",line)); + ++splitter; continue; } - // --- // extract id, entity class name and argument string, // but don't create the actual object yet. // --- - const std::string::size_type n0 = s.find_first_of('='); if (n0 == std::string::npos) { DefaultLogger::get()->warn(AddLineNumber("expected token \'=\'",line)); + ++splitter; continue; } const uint64_t id = strtoul10_64(s.substr(1,n0-1).c_str()); if (!id) { DefaultLogger::get()->warn(AddLineNumber("expected positive, numeric entity id",line)); + ++splitter; continue; } - - const std::string::size_type n1 = s.find_first_of('(',n0); + std::string::size_type n1 = s.find_first_of('(',n0); if (n1 == std::string::npos) { - DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line)); - continue; + has_next = true; + bool ok = false; + for( ++splitter; splitter; ++splitter) { + const std::string& snext = *splitter; + if (snext.empty()) { + continue; + } + + // the next line doesn't start an entity, so maybe it is + // just a continuation for this line, keep going + if (!IsEntityDef(snext)) { + s.append(snext); + n1 = s.find_first_of('(',n0); + ok = (n1 != std::string::npos); + } + else { + break; + } + } + + if(!ok) { + DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line)); + continue; + } } - const std::string::size_type n2 = s.find_last_of(')'); - if (n2 == std::string::npos || n2 < n1) { - DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line)); - continue; + std::string::size_type n2 = s.find_last_of(')'); + if (n2 == std::string::npos || n2 < n1 || n2 == s.length() - 1 || s[n2 + 1] != ';') { + + has_next = true; + bool ok = false; + for( ++splitter; splitter; ++splitter) { + const std::string& snext = *splitter; + if (snext.empty()) { + continue; + } + // the next line doesn't start an entity, so maybe it is + // just a continuation for this line, keep going + if (!IsEntityDef(snext)) { + s.append(snext); + n2 = s.find_last_of(')'); + ok = !(n2 == std::string::npos || n2 < n1 || n2 == s.length() - 1 || s[n2 + 1] != ';'); + } + else { + break; + } + } + if(!ok) { + DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line)); + continue; + } } if (map.find(id) != map.end()) { @@ -222,42 +293,38 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, std::string::size_type ns = n0; do ++ns; while( IsSpace(s.at(ns))); - std::string::size_type ne = n1; do --ne; while( IsSpace(s.at(ne))); - std::string type = s.substr(ns,ne-ns+1); std::transform( type.begin(), type.end(), type.begin(), &Assimp::ToLower<char> ); - const char* sz = scheme.GetStaticStringForToken(type); if(sz) { - const std::string::size_type len = n2-n1+1; char* const copysz = new char[len+1]; std::copy(s.c_str()+n1,s.c_str()+n2+1,copysz); copysz[len] = '\0'; - db.InternInsert(new LazyObject(db,id,line,sz,copysz)); } + if(!has_next) { + ++splitter; + } } if (!splitter) { DefaultLogger::get()->warn("STEP: ignoring unexpected EOF"); } - if ( !DefaultLogger::isNullLogger() ){ + if ( !DefaultLogger::isNullLogger()){ DefaultLogger::get()->debug((Formatter::format(),"STEP: got ",map.size()," object records with ", db.GetRefs().size()," inverse index entries")); } } - // ------------------------------------------------------------------------------------------------ boost::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= NULL*/) { const char* cur = inout; SkipSpaces(&cur); - if (*cur == ',' || IsSpaceOrNewLine(*cur)) { throw STEP::SyntaxError("unexpected token, expected parameter",line); } @@ -339,7 +406,15 @@ boost::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout = cur + 1; - return boost::make_shared<EXPRESS::STRING>(std::string(start, static_cast<size_t>(cur - start))); + // assimp is supposed to output UTF8 strings, so we have to deal + // with foreign encodings. + std::string stemp = std::string(start, static_cast<size_t>(cur - start)); + if(!StringToUTF8(stemp)) { + // TODO: route this to a correct logger with line numbers etc., better error messages + DefaultLogger::get()->error("an error occurred reading escape sequences in ASCII text"); + } + + return boost::make_shared<EXPRESS::STRING>(stemp); } else if (*cur == '\"' ) { throw STEP::SyntaxError("binary data not supported yet",line); @@ -436,7 +511,7 @@ STEP::LazyObject::LazyObject(DB& db, uint64_t id,uint64_t /*line*/, const char* --skip_depth; } - if (skip_depth == 1 && *a=='#') { + if (skip_depth >= 1 && *a=='#') { const char* tmp; const int64_t num = static_cast<int64_t>( strtoul10_64(a+1,&tmp) ); db.MarkRef(num,id); diff --git a/src/3rdparty/assimp/code/STEPFileReader.h b/src/3rdparty/assimp/code/STEPFileReader.h index 2c132c658..432c620db 100644 --- a/src/3rdparty/assimp/code/STEPFileReader.h +++ b/src/3rdparty/assimp/code/STEPFileReader.h @@ -47,12 +47,10 @@ namespace Assimp { namespace STEP { // ### Parsing a STEP file is a twofold procedure ### - // -------------------------------------------------------------------------- // 1) read file header and return to caller, who checks if the // file is of a supported schema .. DB* ReadFileHeader(boost::shared_ptr<IOStream> stream); - // -------------------------------------------------------------------------- // 2) read the actual file contents using a user-supplied set of // conversion functions to interpret the data. @@ -60,8 +58,6 @@ namespace STEP { template <size_t N, size_t N2> inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) { return ReadFile(db,scheme,arr,N,arr2,N2); } - - } // ! STEP } // ! Assimp diff --git a/src/3rdparty/assimp/code/STLExporter.cpp b/src/3rdparty/assimp/code/STLExporter.cpp index 918d692fb..7824a68fa 100644 --- a/src/3rdparty/assimp/code/STLExporter.cpp +++ b/src/3rdparty/assimp/code/STLExporter.cpp @@ -57,6 +57,23 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene // we're still here - export successfully completed. Write the file. boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output .stl file: " + std::string(pFile)); + } + + outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1); +} +void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) +{ + // invoke the exporter + STLExporter exporter(pFile, pScene, true); + + // we're still here - export successfully completed. Write the file. + boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); + if(outfile == NULL) { + throw DeadlyExportError("could not open output .stl file: " + std::string(pFile)); + } + outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1); } @@ -64,7 +81,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene // ------------------------------------------------------------------------------------------------ -STLExporter :: STLExporter(const char* _filename, const aiScene* pScene) +STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool binary) : filename(_filename) , pScene(pScene) , endl("\n") @@ -72,14 +89,31 @@ STLExporter :: STLExporter(const char* _filename, const aiScene* pScene) // make sure that all formatting happens using the standard, C locale and not the user's current locale const std::locale& l = std::locale("C"); mOutput.imbue(l); - - const std::string& name = "AssimpScene"; + if (binary) { + char buf[80] = {0} ; + buf[0] = 'A'; buf[1] = 's'; buf[2] = 's'; buf[3] = 'i'; buf[4] = 'm'; buf[5] = 'p'; + buf[6] = 'S'; buf[7] = 'c'; buf[8] = 'e'; buf[9] = 'n'; buf[10] = 'e'; + mOutput.write(buf, 80); + unsigned int meshnum = 0; + for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { + for (unsigned int j = 0; j < pScene->mMeshes[i]->mNumFaces; ++j) { + meshnum++; + } + } + AI_SWAP4(meshnum); + mOutput.write((char *)&meshnum, 4); + for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { + WriteMeshBinary(pScene->mMeshes[i]); + } + } else { + const std::string& name = "AssimpScene"; - mOutput << "solid " << name << endl; - for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { - WriteMesh(pScene->mMeshes[i]); + mOutput << "solid " << name << endl; + for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) { + WriteMesh(pScene->mMeshes[i]); + } + mOutput << "endsolid " << name << endl; } - mOutput << "endsolid " << name << endl; } // ------------------------------------------------------------------------------------------------ @@ -109,4 +143,31 @@ void STLExporter :: WriteMesh(const aiMesh* m) } } +void STLExporter :: WriteMeshBinary(const aiMesh* m) +{ + for (unsigned int i = 0; i < m->mNumFaces; ++i) { + const aiFace& f = m->mFaces[i]; + // we need per-face normals. We specified aiProcess_GenNormals as pre-requisite for this exporter, + // but nonetheless we have to expect per-vertex normals. + aiVector3D nor; + if (m->mNormals) { + for(unsigned int a = 0; a < f.mNumIndices; ++a) { + nor += m->mNormals[f.mIndices[a]]; + } + nor.Normalize(); + } + float nx = nor.x, ny = nor.y, nz = nor.z; + AI_SWAP4(nx); AI_SWAP4(ny); AI_SWAP4(nz); + mOutput.write((char *)&nx, 4); mOutput.write((char *)&ny, 4); mOutput.write((char *)&nz, 4); + for(unsigned int a = 0; a < f.mNumIndices; ++a) { + const aiVector3D& v = m->mVertices[f.mIndices[a]]; + float vx = v.x, vy = v.y, vz = v.z; + AI_SWAP4(vx); AI_SWAP4(vy); AI_SWAP4(vz); + mOutput.write((char *)&vx, 4); mOutput.write((char *)&vy, 4); mOutput.write((char *)&vz, 4); + } + char dummy[2] = {0}; + mOutput.write(dummy, 2); + } +} + #endif diff --git a/src/3rdparty/assimp/code/STLExporter.h b/src/3rdparty/assimp/code/STLExporter.h index 571f2dca4..71f065762 100644 --- a/src/3rdparty/assimp/code/STLExporter.h +++ b/src/3rdparty/assimp/code/STLExporter.h @@ -59,7 +59,7 @@ class STLExporter { public: /// Constructor for a specific scene to export - STLExporter(const char* filename, const aiScene* pScene); + STLExporter(const char* filename, const aiScene* pScene, bool binary = false); public: @@ -69,6 +69,7 @@ public: private: void WriteMesh(const aiMesh* m); + void WriteMeshBinary(const aiMesh* m); private: diff --git a/src/3rdparty/assimp/code/STLLoader.cpp b/src/3rdparty/assimp/code/STLLoader.cpp index feb7711e7..567f4875b 100644 --- a/src/3rdparty/assimp/code/STLLoader.cpp +++ b/src/3rdparty/assimp/code/STLLoader.cpp @@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +namespace { static const aiImporterDesc desc = { "Stereolithography (STL) Importer", "", @@ -64,6 +65,39 @@ static const aiImporterDesc desc = { "stl" }; +// A valid binary STL buffer should consist of the following elements, in order: +// 1) 80 byte header +// 2) 4 byte face count +// 3) 50 bytes per face +bool IsBinarySTL(const char* buffer, unsigned int fileSize) { + if (fileSize < 84) + return false; + + const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80); + const uint32_t expectedBinaryFileSize = faceCount * 50 + 84; + + return expectedBinaryFileSize == fileSize; +} + +// An ascii STL buffer will begin with "solid NAME", where NAME is optional. +// Note: The "solid NAME" check is necessary, but not sufficient, to determine +// if the buffer is ASCII; a binary header could also begin with "solid NAME". +bool IsAsciiSTL(const char* buffer, unsigned int fileSize) { + if (IsBinarySTL(buffer, fileSize)) + return false; + + const char* bufferEnd = buffer + fileSize; + + if (!SkipSpaces(&buffer)) + return false; + + if (buffer + 5 >= bufferEnd) + return false; + + return strncmp(buffer, "solid", 5) == 0; +} +} // namespace + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer STLImporter::STLImporter() @@ -119,8 +153,8 @@ void STLImporter::InternReadFile( const std::string& pFile, this->pScene = pScene; this->mBuffer = &mBuffer2[0]; - // the default vertex color is white - clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 1.0f; + // the default vertex color is light gray. + clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 0.6f; // allocate one mesh pScene->mNumMeshes = 1; @@ -136,12 +170,13 @@ void STLImporter::InternReadFile( const std::string& pFile, bool bMatClr = false; - // check whether the file starts with 'solid' - - // in this case we can simply assume it IS a text file. finished. - if (!::strncmp(mBuffer,"solid",5)) { + if (IsBinarySTL(mBuffer, fileSize)) { + bMatClr = LoadBinaryFile(); + } else if (IsAsciiSTL(mBuffer, fileSize)) { LoadASCIIFile(); + } else { + throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + "."); } - else bMatClr = LoadBinaryFile(); // now copy faces pMesh->mFaces = new aiFace[pMesh->mNumFaces]; @@ -154,13 +189,14 @@ void STLImporter::InternReadFile( const std::string& pFile, } } - // create a single default material - everything white, as we have vertex colors + // create a single default material, using a light gray diffuse color for consistency with + // other geometric types (e.g., PLY). aiMaterial* pcMat = new aiMaterial(); aiString s; s.Set(AI_DEFAULT_MATERIAL_NAME); pcMat->AddProperty(&s, AI_MATKEY_NAME); - aiColor4D clrDiffuse(1.0f,1.0f,1.0f,1.0f); + aiColor4D clrDiffuse(0.6f,0.6f,0.6f,1.0f); if (bMatClr) { clrDiffuse = clrColorDefault; } @@ -179,7 +215,11 @@ void STLImporter::LoadASCIIFile() { aiMesh* pMesh = pScene->mMeshes[0]; - const char* sz = mBuffer + 5; // skip the "solid" + const char* sz = mBuffer; + SkipSpaces(&sz); + ai_assert(!IsLineEnd(sz)); + + sz += 5; // skip the "solid" SkipSpaces(&sz); const char* szMe = sz; while (!::IsSpaceOrNewLine(*sz)) { @@ -203,7 +243,7 @@ void STLImporter::LoadASCIIFile() pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; unsigned int curFace = 0, curVertex = 3; - while (true) + for ( ;; ) { // go to the next token if(!SkipSpacesAndLineEnd(&sz)) @@ -382,9 +422,9 @@ bool STLImporter::LoadBinaryFile() DefaultLogger::get()->info("STL: Mesh has vertex colors"); } - aiColor4D* clr = &pMesh->mColors[0][pMesh->mNumFaces*3]; + aiColor4D* clr = &pMesh->mColors[0][i*3]; clr->a = 1.0f; - if (bIsMaterialise) // fuck, this is reversed + if (bIsMaterialise) // this is reversed { clr->r = (color & 0x31u) / 31.0f; clr->g = ((color & (0x31u<<5))>>5u) / 31.0f; diff --git a/src/3rdparty/assimp/code/SceneCombiner.cpp b/src/3rdparty/assimp/code/SceneCombiner.cpp index bfdff22b9..26d0444a2 100644 --- a/src/3rdparty/assimp/code/SceneCombiner.cpp +++ b/src/3rdparty/assimp/code/SceneCombiner.cpp @@ -881,6 +881,59 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/, } // ------------------------------------------------------------------------------------------------ +void SceneCombiner::MergeMaterials(aiMaterial** dest, + std::vector<aiMaterial*>::const_iterator begin, + std::vector<aiMaterial*>::const_iterator end) +{ + ai_assert(NULL != dest); + + if (begin == end) { + *dest = NULL; // no materials ... + return; + } + + // Allocate the output material + aiMaterial* out = *dest = new aiMaterial(); + + // Get the maximal number of properties + unsigned int size = 0; + for (std::vector<aiMaterial*>::const_iterator it = begin; it != end; ++it) { + size += (*it)->mNumProperties; + } + + out->Clear(); + delete[] out->mProperties; + + out->mNumAllocated = size; + out->mNumProperties = 0; + out->mProperties = new aiMaterialProperty*[out->mNumAllocated]; + + for (std::vector<aiMaterial*>::const_iterator it = begin; it != end; ++it) { + for(unsigned int i = 0; i < (*it)->mNumProperties; ++i) { + aiMaterialProperty* sprop = (*it)->mProperties[i]; + + // Test if we already have a matching property + const aiMaterialProperty* prop_exist; + if(aiGetMaterialProperty(out, sprop->mKey.C_Str(), sprop->mType, sprop->mIndex, &prop_exist) != AI_SUCCESS) { + // If not, we add it to the new material + aiMaterialProperty* prop = out->mProperties[out->mNumProperties] = new aiMaterialProperty(); + + prop->mDataLength = sprop->mDataLength; + prop->mData = new char[prop->mDataLength]; + ::memcpy(prop->mData, sprop->mData, prop->mDataLength); + + prop->mIndex = sprop->mIndex; + prop->mSemantic = sprop->mSemantic; + prop->mKey = sprop->mKey; + prop->mType = sprop->mType; + + out->mNumProperties++; + } + } + } +} + +// ------------------------------------------------------------------------------------------------ template <typename Type> inline void CopyPtrArray (Type**& dest, const Type* const * src, unsigned int num) { @@ -1012,6 +1065,10 @@ void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src) ai_assert(NULL != _dest && NULL != src); aiMaterial* dest = (aiMaterial*) ( *_dest = new aiMaterial() ); + + dest->Clear(); + delete[] dest->mProperties; + dest->mNumAllocated = src->mNumAllocated; dest->mNumProperties = src->mNumProperties; dest->mProperties = new aiMaterialProperty* [dest->mNumAllocated]; diff --git a/src/3rdparty/assimp/code/SceneCombiner.h b/src/3rdparty/assimp/code/SceneCombiner.h index 76801097c..3bcc478e4 100644 --- a/src/3rdparty/assimp/code/SceneCombiner.h +++ b/src/3rdparty/assimp/code/SceneCombiner.h @@ -248,6 +248,20 @@ public: static void MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it, std::vector<aiMesh*>::const_iterator end); + // ------------------------------------------------------------------- + /** Merges two or more materials + * + * The materials should be complementary as much as possible. In case + * of a property present in different materials, the first occurence + * is used. + * + * @param dest Destination material. Must be empty. + * @param begin First material to be processed + * @param end Points to the material after the last material to be processed + */ + static void MergeMaterials(aiMaterial** dest, + std::vector<aiMaterial*>::const_iterator begin, + std::vector<aiMaterial*>::const_iterator end); // ------------------------------------------------------------------- /** Builds a list of uniquely named bones in a mesh list diff --git a/src/3rdparty/assimp/code/ScenePreprocessor.cpp b/src/3rdparty/assimp/code/ScenePreprocessor.cpp index f2433b7af..4e3ff973c 100644 --- a/src/3rdparty/assimp/code/ScenePreprocessor.cpp +++ b/src/3rdparty/assimp/code/ScenePreprocessor.cpp @@ -72,7 +72,7 @@ void ScenePreprocessor::ProcessScene () aiColor3D clr(0.6f,0.6f,0.6f); helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE); - // setup the default name to make this material identifyable + // setup the default name to make this material identifiable name.Set(AI_DEFAULT_MATERIAL_NAME); helper->AddProperty(&name,AI_MATKEY_NAME); diff --git a/src/3rdparty/assimp/code/ScenePreprocessor.h b/src/3rdparty/assimp/code/ScenePreprocessor.h index a24c652dd..cfa0892be 100644 --- a/src/3rdparty/assimp/code/ScenePreprocessor.h +++ b/src/3rdparty/assimp/code/ScenePreprocessor.h @@ -54,7 +54,7 @@ namespace Assimp { * importer, such as aiMesh::mPrimitiveTypes. */ // ---------------------------------------------------------------------------------- -class ScenePreprocessor +class ASSIMP_API ScenePreprocessor { // Make ourselves a friend of the corresponding test unit. friend class ::ScenePreprocessorTest; diff --git a/src/3rdparty/assimp/code/ScenePrivate.h b/src/3rdparty/assimp/code/ScenePrivate.h index e8c3c3793..af1966457 100644 --- a/src/3rdparty/assimp/code/ScenePrivate.h +++ b/src/3rdparty/assimp/code/ScenePrivate.h @@ -53,6 +53,7 @@ struct ScenePrivateData { ScenePrivateData() : mOrigImporter() , mPPStepsApplied() + , mIsCopy() {} // Importer that originally loaded the scene though the C-API @@ -61,6 +62,13 @@ struct ScenePrivateData { // List of postprocessing steps already applied to the scene. unsigned int mPPStepsApplied; + + // true if the scene is a copy made with aiCopyScene() + // or the corresponding C++ API. This means that user code + // may have made modifications to it, so mPPStepsApplied + // and mOrigImporter are no longer safe to rely on and only + // serve informative purposes. + bool mIsCopy; }; // Access private data stored in the scene diff --git a/src/3rdparty/assimp/code/SmoothingGroups.h b/src/3rdparty/assimp/code/SmoothingGroups.h index 5284b6fa6..19ecee6df 100644 --- a/src/3rdparty/assimp/code/SmoothingGroups.h +++ b/src/3rdparty/assimp/code/SmoothingGroups.h @@ -52,7 +52,7 @@ struct FaceWithSmoothingGroup { // let the rest uninitialized for performance - in release builds. // in debug builds set all indices to a common magic value -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG this->mIndices[0] = 0xffffffff; this->mIndices[1] = 0xffffffff; this->mIndices[2] = 0xffffffff; diff --git a/src/3rdparty/assimp/code/SortByPTypeProcess.cpp b/src/3rdparty/assimp/code/SortByPTypeProcess.cpp index 89257cd8c..2b3c9d5c0 100644 --- a/src/3rdparty/assimp/code/SortByPTypeProcess.cpp +++ b/src/3rdparty/assimp/code/SortByPTypeProcess.cpp @@ -151,7 +151,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene) std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin(); for (unsigned int i = 0; i < pScene->mNumMeshes;++i) { - aiMesh* mesh = pScene->mMeshes[i]; + aiMesh* const mesh = pScene->mMeshes[i]; ai_assert(0 != mesh->mPrimitiveTypes); // if there's just one primitive type in the mesh there's nothing to do for us @@ -367,6 +367,9 @@ void SortByPTypeProcess::Execute( aiScene* pScene) // delete the input mesh delete mesh; + + // avoid invalid pointer + pScene->mMeshes[i] = NULL; } if (outMeshes.empty()) diff --git a/src/3rdparty/assimp/code/SortByPTypeProcess.h b/src/3rdparty/assimp/code/SortByPTypeProcess.h index 0192f958f..455215f03 100644 --- a/src/3rdparty/assimp/code/SortByPTypeProcess.h +++ b/src/3rdparty/assimp/code/SortByPTypeProcess.h @@ -55,7 +55,7 @@ namespace Assimp { * A mesh with 5 lines, 3 points and 145 triangles would be split in 3 * submeshes. */ -class SortByPTypeProcess : public BaseProcess +class ASSIMP_API SortByPTypeProcess : public BaseProcess { public: diff --git a/src/3rdparty/assimp/code/SpatialSort.cpp b/src/3rdparty/assimp/code/SpatialSort.cpp index 67e41d388..e54665609 100644 --- a/src/3rdparty/assimp/code/SpatialSort.cpp +++ b/src/3rdparty/assimp/code/SpatialSort.cpp @@ -329,7 +329,7 @@ unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill,f ++t; } -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG // debug invariant: mPositions[i].mIndex values must range from 0 to mPositions.size()-1 for (size_t i = 0; i < fill.size(); ++i) { diff --git a/src/3rdparty/assimp/code/SplitLargeMeshes.h b/src/3rdparty/assimp/code/SplitLargeMeshes.h index d40414e3b..68e4540a1 100644 --- a/src/3rdparty/assimp/code/SplitLargeMeshes.h +++ b/src/3rdparty/assimp/code/SplitLargeMeshes.h @@ -76,12 +76,12 @@ class SplitLargeMeshesProcess_Vertex; #endif // --------------------------------------------------------------------------- -/** Postprocessing filter to split large meshes into submeshes +/** Post-processing filter to split large meshes into sub-meshes * * Applied BEFORE the JoinVertices-Step occurs. * Returns NON-UNIQUE vertices, splits by triangle number. */ -class SplitLargeMeshesProcess_Triangle : public BaseProcess +class ASSIMP_API SplitLargeMeshesProcess_Triangle : public BaseProcess { friend class SplitLargeMeshesProcess_Vertex; @@ -144,12 +144,12 @@ public: // --------------------------------------------------------------------------- -/** Postprocessing filter to split large meshes into submeshes +/** Post-processing filter to split large meshes into sub-meshes * * Applied AFTER the JoinVertices-Step occurs. * Returns UNIQUE vertices, splits by vertex number. */ -class SplitLargeMeshesProcess_Vertex : public BaseProcess +class ASSIMP_API SplitLargeMeshesProcess_Vertex : public BaseProcess { public: diff --git a/src/3rdparty/assimp/code/StreamReader.h b/src/3rdparty/assimp/code/StreamReader.h index cd2453af2..73467943b 100644 --- a/src/3rdparty/assimp/code/StreamReader.h +++ b/src/3rdparty/assimp/code/StreamReader.h @@ -193,7 +193,7 @@ public: // --------------------------------------------------------------------- /** Increase the file pointer (relative seeking) */ - void IncPtr(int plus) { + void IncPtr(size_t plus) { current += plus; if (current > limit) { throw DeadlyImportError("End of file or read limit was reached"); diff --git a/src/3rdparty/assimp/code/StringComparison.h b/src/3rdparty/assimp/code/StringComparison.h index 3769e8a7c..72dee86dd 100644 --- a/src/3rdparty/assimp/code/StringComparison.h +++ b/src/3rdparty/assimp/code/StringComparison.h @@ -87,7 +87,7 @@ inline unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number) // print all future zeroes from now mustPrint = true; - *out++ = '0'+digit; + *out++ = '0'+static_cast<char>(digit); ++written; number -= digit*cur; diff --git a/src/3rdparty/assimp/code/Subdivision.cpp b/src/3rdparty/assimp/code/Subdivision.cpp index e4dd1b4f1..483712c56 100644 --- a/src/3rdparty/assimp/code/Subdivision.cpp +++ b/src/3rdparty/assimp/code/Subdivision.cpp @@ -383,7 +383,7 @@ void CatmullClarkSubdivider::InternSubdivide ( } // check the other way round for consistency -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG for (size_t t = 0; t < ofsadjvec.size()-1; ++t) { for (unsigned int m = 0; m < cntadjfac[t]; ++m) { @@ -530,7 +530,7 @@ void CatmullClarkSubdivider::InternSubdivide ( ai_assert(adj[o]-moffsets[nidx].first < mp->mNumFaces); const aiFace& f = mp->mFaces[adj[o]-moffsets[nidx].first]; -# ifdef _DEBUG +# ifdef ASSIMP_BUILD_DEBUG bool haveit = false; # endif @@ -553,7 +553,7 @@ void CatmullClarkSubdivider::InternSubdivide ( // fixme: replace with mod face.mNumIndices? R += c0.midpoint+c1.midpoint; -# ifdef _DEBUG +# ifdef ASSIMP_BUILD_DEBUG haveit = true; # endif break; diff --git a/src/3rdparty/assimp/code/TinyFormatter.h b/src/3rdparty/assimp/code/TinyFormatter.h index edc00e40e..9818dc0bb 100644 --- a/src/3rdparty/assimp/code/TinyFormatter.h +++ b/src/3rdparty/assimp/code/TinyFormatter.h @@ -90,6 +90,19 @@ public: underlying << sin; } + + // The problem described here: + // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462 + // can also cause trouble here. Apparently, older gcc versions sometimes copy temporaries + // being bound to const ref& function parameters. Copying streams is not permitted, though. + // This workaround avoids this by manually specifying a copy ctor. +#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) + basic_formatter(const basic_formatter& other) { + underlying << (string)other; + } +#endif + + public: operator string () const { diff --git a/src/3rdparty/assimp/code/TriangulateProcess.cpp b/src/3rdparty/assimp/code/TriangulateProcess.cpp index 1b6627720..1e3b96c11 100644 --- a/src/3rdparty/assimp/code/TriangulateProcess.cpp +++ b/src/3rdparty/assimp/code/TriangulateProcess.cpp @@ -188,6 +188,8 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) FILE* fout = fopen(POLY_OUTPUT_FILE,"a"); #endif + const aiVector3D* verts = pMesh->mVertices; + // use boost::scoped_array to avoid slow std::vector<bool> specialiations boost::scoped_array<bool> done(new bool[max_out]); for( unsigned int a = 0; a < pMesh->mNumFaces; a++) { @@ -216,24 +218,59 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) face.mIndices = NULL; continue; - } /* does not handle concave quads + } // optimized code for quadrilaterals else if ( face.mNumIndices == 4) { + + // quads can have at maximum one concave vertex. Determine + // this vertex (if it exists) and start tri-fanning from + // it. + unsigned int start_vertex = 0; + for (unsigned int i = 0; i < 4; ++i) { + const aiVector3D& v0 = verts[face.mIndices[(i+3) % 4]]; + const aiVector3D& v1 = verts[face.mIndices[(i+2) % 4]]; + const aiVector3D& v2 = verts[face.mIndices[(i+1) % 4]]; + + const aiVector3D& v = verts[face.mIndices[i]]; + + aiVector3D left = (v0-v); + aiVector3D diag = (v1-v); + aiVector3D right = (v2-v); + + left.Normalize(); + diag.Normalize(); + right.Normalize(); + + const float angle = acos(left*diag) + acos(right*diag); + if (angle > AI_MATH_PI_F) { + // this is the concave point + start_vertex = i; + break; + } + } + + const unsigned int temp[] = {face.mIndices[0], face.mIndices[1], face.mIndices[2], face.mIndices[3]}; + aiFace& nface = *curOut++; nface.mNumIndices = 3; nface.mIndices = face.mIndices; + nface.mIndices[0] = temp[start_vertex]; + nface.mIndices[1] = temp[(start_vertex + 1) % 4]; + nface.mIndices[2] = temp[(start_vertex + 2) % 4]; + aiFace& sface = *curOut++; sface.mNumIndices = 3; sface.mIndices = new unsigned int[3]; - sface.mIndices[0] = face.mIndices[0]; - sface.mIndices[1] = face.mIndices[2]; - sface.mIndices[2] = face.mIndices[3]; - + sface.mIndices[0] = temp[start_vertex]; + sface.mIndices[1] = temp[(start_vertex + 2) % 4]; + sface.mIndices[2] = temp[(start_vertex + 3) % 4]; + + // prevent double deletion of the indices field face.mIndices = NULL; continue; - } */ + } else { // A polygon with more than 3 vertices can be either concave or convex. @@ -246,7 +283,6 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) // We project it onto a plane to get a 2d triangle. // Collect all vertices of of the polygon. - const aiVector3D* verts = pMesh->mVertices; for (tmp = 0; tmp < max; ++tmp) { temp_verts3d[tmp] = verts[idx[tmp]]; } diff --git a/src/3rdparty/assimp/code/TriangulateProcess.h b/src/3rdparty/assimp/code/TriangulateProcess.h index fc1c0c253..a75c8d822 100644 --- a/src/3rdparty/assimp/code/TriangulateProcess.h +++ b/src/3rdparty/assimp/code/TriangulateProcess.h @@ -49,15 +49,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct aiMesh; class TriangulateProcessTest; -namespace Assimp -{ + +namespace Assimp { // --------------------------------------------------------------------------- /** The TriangulateProcess splits up all faces with more than three indices * into triangles. You usually want this to happen because the graphics cards * need their data as triangles. */ -class TriangulateProcess : public BaseProcess +class ASSIMP_API TriangulateProcess : public BaseProcess { public: diff --git a/src/3rdparty/assimp/code/ValidateDataStructure.cpp b/src/3rdparty/assimp/code/ValidateDataStructure.cpp index 378da435f..20b0b1892 100644 --- a/src/3rdparty/assimp/code/ValidateDataStructure.cpp +++ b/src/3rdparty/assimp/code/ValidateDataStructure.cpp @@ -86,7 +86,7 @@ AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...) ai_assert(iLen > 0); va_end(args); -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG ai_assert( false ); #endif throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen)); diff --git a/src/3rdparty/assimp/code/ValidateDataStructure.h b/src/3rdparty/assimp/code/ValidateDataStructure.h index 0b5942f32..2b7fa3721 100644 --- a/src/3rdparty/assimp/code/ValidateDataStructure.h +++ b/src/3rdparty/assimp/code/ValidateDataStructure.h @@ -82,7 +82,7 @@ protected: /** Report a validation error. This will throw an exception, * control won't return. * @param msg Format string for sprintf().*/ - AI_WONT_RETURN void ReportError(const char* msg,...); + AI_WONT_RETURN void ReportError(const char* msg,...) AI_WONT_RETURN_SUFFIX; // ------------------------------------------------------------------- diff --git a/src/3rdparty/assimp/code/VertexTriangleAdjacency.h b/src/3rdparty/assimp/code/VertexTriangleAdjacency.h index 3e429adfa..9a60fc942 100644 --- a/src/3rdparty/assimp/code/VertexTriangleAdjacency.h +++ b/src/3rdparty/assimp/code/VertexTriangleAdjacency.h @@ -56,7 +56,7 @@ namespace Assimp { * @note Although it is called #VertexTriangleAdjacency, the current version does also * support arbitrary polygons. */ // -------------------------------------------------------------------------------------------- -class VertexTriangleAdjacency +class ASSIMP_API VertexTriangleAdjacency { public: diff --git a/src/3rdparty/assimp/code/XFileHelper.h b/src/3rdparty/assimp/code/XFileHelper.h index 7a1fbd049..792055437 100644 --- a/src/3rdparty/assimp/code/XFileHelper.h +++ b/src/3rdparty/assimp/code/XFileHelper.h @@ -85,7 +85,9 @@ struct Material aiColor3D mEmissive; std::vector<TexEntry> mTextures; - Material() { mIsReference = false; } + size_t sceneIndex; ///< the index under which it was stored in the scene's material list + + Material() { mIsReference = false; sceneIndex = SIZE_MAX; } }; /** Helper structure to represent a bone weight */ diff --git a/src/3rdparty/assimp/code/XFileImporter.cpp b/src/3rdparty/assimp/code/XFileImporter.cpp index d444135aa..d100692d3 100644 --- a/src/3rdparty/assimp/code/XFileImporter.cpp +++ b/src/3rdparty/assimp/code/XFileImporter.cpp @@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; static const aiImporterDesc desc = { - "Collada Importer", + "Direct3D XFile Importer", "", "", "", @@ -110,10 +110,6 @@ void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, I if( fileSize < 16) throw DeadlyImportError( "XFile is too small."); - // need to clear members - this method might be called multiple - // times on a single XFileImporter instance. - mImportedMats.clear(); - // in the hope that binary files will never start with a BOM ... mBuffer.resize( fileSize + 1); file->Read( &mBuffer.front(), 1, fileSize); @@ -132,7 +128,7 @@ void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, I // ------------------------------------------------------------------------------------------------ // Constructs the return data structure out of the imported data. -void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, const XFile::Scene* pData) +void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData) { // Read the global materials first so that meshes referring to them can find them later ConvertMaterials( pScene, pData->mGlobalMaterials); @@ -233,8 +229,8 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec std::vector<aiMesh*> meshes; for( unsigned int a = 0; a < pMeshes.size(); a++) { - const XFile::Mesh* sourceMesh = pMeshes[a]; - // first convert its materials so that we can find them when searching by name afterwards + XFile::Mesh* sourceMesh = pMeshes[a]; + // first convert its materials so that we can find them with their index afterwards ConvertMaterials( pScene, sourceMesh->mMaterials); unsigned int numMaterials = std::max( (unsigned int)sourceMesh->mMaterials.size(), 1u); @@ -272,15 +268,11 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec aiMesh* mesh = new aiMesh; meshes.push_back( mesh); - // find the material by name in the scene's material list. Either own material - // or referenced material, it should already be found there + // find the material in the scene's material list. Either own material + // or referenced material, it should already have a valid index if( sourceMesh->mFaceMaterials.size() > 0) { - std::map<std::string, unsigned int>::const_iterator matIt = mImportedMats.find( sourceMesh->mMaterials[b].mName); - if( matIt == mImportedMats.end()) - mesh->mMaterialIndex = 0; - else - mesh->mMaterialIndex = matIt->second; + mesh->mMaterialIndex = sourceMesh->mMaterials[b].sceneIndex; } else { mesh->mMaterialIndex = 0; @@ -554,32 +546,52 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData // ------------------------------------------------------------------------------------------------ // Converts all materials in the given array and stores them in the scene's material list. -void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::Material>& pMaterials) +void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials) { // count the non-referrer materials in the array - unsigned int numMaterials = 0; + unsigned int numNewMaterials = 0; for( unsigned int a = 0; a < pMaterials.size(); a++) if( !pMaterials[a].mIsReference) - numMaterials++; - - if( numMaterials == 0) - return; + numNewMaterials++; // resize the scene's material list to offer enough space for the new materials - aiMaterial** prevMats = pScene->mMaterials; - pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials + numMaterials]; - if( prevMats) - { - memcpy( pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof( aiMaterial*)); - delete [] prevMats; - } + if( numNewMaterials > 0 ) + { + aiMaterial** prevMats = pScene->mMaterials; + pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials + numNewMaterials]; + if( prevMats) + { + memcpy( pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof( aiMaterial*)); + delete [] prevMats; + } + } // convert all the materials given in the array for( unsigned int a = 0; a < pMaterials.size(); a++) { - const XFile::Material& oldMat = pMaterials[a]; + XFile::Material& oldMat = pMaterials[a]; if( oldMat.mIsReference) - continue; + { + // find the material it refers to by name, and store its index + for( size_t a = 0; a < pScene->mNumMaterials; ++a ) + { + aiString name; + pScene->mMaterials[a]->Get( AI_MATKEY_NAME, name); + if( strcmp( name.C_Str(), oldMat.mName.data()) == 0 ) + { + oldMat.sceneIndex = a; + break; + } + } + + if( oldMat.sceneIndex == SIZE_MAX ) + { + DefaultLogger::get()->warn( boost::str( boost::format( "Could not resolve global material reference \"%s\"") % oldMat.mName)); + oldMat.sceneIndex = 0; + } + + continue; + } aiMaterial* mat = new aiMaterial; aiString name; @@ -594,8 +606,9 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile:: mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL); // material colours - // FIX: Setup this as ambient not as emissive color - mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_AMBIENT); + // Unclear: there's no ambient colour, but emissive. What to put for ambient? + // Probably nothing at all, let the user select a suitable default. + mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS); @@ -677,7 +690,7 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile:: } pScene->mMaterials[pScene->mNumMaterials] = mat; - mImportedMats[oldMat.mName] = pScene->mNumMaterials; + oldMat.sceneIndex = pScene->mNumMaterials; pScene->mNumMaterials++; } } diff --git a/src/3rdparty/assimp/code/XFileImporter.h b/src/3rdparty/assimp/code/XFileImporter.h index cefb68601..39f3d827a 100644 --- a/src/3rdparty/assimp/code/XFileImporter.h +++ b/src/3rdparty/assimp/code/XFileImporter.h @@ -99,8 +99,7 @@ protected: * @param pData The imported data in the internal temporary * representation. */ - void CreateDataRepresentationFromImport( aiScene* pScene, - const XFile::Scene* pData); + void CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData); // ------------------------------------------------------------------- /** Recursively creates scene nodes from the imported hierarchy. @@ -139,15 +138,11 @@ protected: * @param pScene The scene to hold the converted materials. * @param pMaterials The material array to convert. */ - void ConvertMaterials( aiScene* pScene, - const std::vector<XFile::Material>& pMaterials); + void ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials); protected: /** Buffer to hold the loaded file */ std::vector<char> mBuffer; - - /** Imported materials: index in the scene's material list by name */ - std::map<std::string, unsigned int> mImportedMats; }; } // end of namespace Assimp diff --git a/src/3rdparty/assimp/code/XFileParser.cpp b/src/3rdparty/assimp/code/XFileParser.cpp index 41bc1d55a..a89b12d95 100644 --- a/src/3rdparty/assimp/code/XFileParser.cpp +++ b/src/3rdparty/assimp/code/XFileParser.cpp @@ -136,6 +136,9 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer) ThrowException( boost::str( boost::format( "Unknown float size %1% specified in xfile header.") % mBinaryFloatSize)); + // The x format specifies size in bits, but we work in bytes + mBinaryFloatSize /= 8; + P += 16; // If this is a compressed X file, apply the inflate algorithm to it @@ -460,7 +463,7 @@ void XFileParser::ParseDataObjectMesh( Mesh* pMesh) Face& face = pMesh->mPosFaces[a]; for( unsigned int b = 0; b < numIndices; b++) face.mIndices.push_back( ReadInt()); - CheckForSeparator(); + TestForSeparator(); } // here, other data objects may follow @@ -583,7 +586,7 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh) for( unsigned int b = 0; b < numIndices; b++) face.mIndices.push_back( ReadInt()); - CheckForSeparator(); + TestForSeparator(); } CheckForClosingBrace(); diff --git a/src/3rdparty/assimp/code/XFileParser.h b/src/3rdparty/assimp/code/XFileParser.h index 3ada49d68..6ab292787 100644 --- a/src/3rdparty/assimp/code/XFileParser.h +++ b/src/3rdparty/assimp/code/XFileParser.h @@ -74,7 +74,7 @@ public: ~XFileParser(); /** Returns the temporary representation of the imported data */ - const XFile::Scene* GetImportedData() const { return mScene; } + XFile::Scene* GetImportedData() const { return mScene; } protected: void ParseFile(); @@ -144,7 +144,7 @@ protected: protected: unsigned int mMajorVersion, mMinorVersion; ///< version numbers bool mIsBinaryFormat; ///< true if the file is in binary, false if it's in text form - unsigned int mBinaryFloatSize; ///< float size, either 32 or 64 bits + unsigned int mBinaryFloatSize; ///< float size in bytes, either 4 or 8 // counter for number arrays in binary format unsigned int mBinaryNumCount; diff --git a/src/3rdparty/assimp/code/XGLLoader.cpp b/src/3rdparty/assimp/code/XGLLoader.cpp index c697580b0..49ff68619 100644 --- a/src/3rdparty/assimp/code/XGLLoader.cpp +++ b/src/3rdparty/assimp/code/XGLLoader.cpp @@ -77,8 +77,11 @@ struct free_it void* free; }; +namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp template<> const std::string LogFunctions<XGLImporter>::log_prefix = "XGL: "; +} + static const aiImporterDesc desc = { "XGL Importer", "", @@ -394,14 +397,14 @@ aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* cl // XXX } else if (s == "meshref") { - const int id = ReadIndexFromText(); + const unsigned int id = static_cast<unsigned int>( ReadIndexFromText() ); std::multimap<unsigned int, aiMesh*>::iterator it = scope.meshes.find(id), end = scope.meshes.end(); if (it == end) { ThrowException("<meshref> index out of range"); } - for(; it != end && (*it).first == static_cast<unsigned int>(id); ++it) { + for(; it != end && (*it).first == id; ++it) { // ok, this is n^2 and should get optimized one day aiMesh* const m = (*it).second; diff --git a/src/3rdparty/assimp/code/fast_atof.h b/src/3rdparty/assimp/code/fast_atof.h index c9ef1ffd6..580447b9b 100644 --- a/src/3rdparty/assimp/code/fast_atof.h +++ b/src/3rdparty/assimp/code/fast_atof.h @@ -16,27 +16,28 @@ #define __FAST_A_TO_F_H_INCLUDED__ #include <math.h> +#include <limits.h> namespace Assimp { -const float fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug - 0.f, - 0.1f, - 0.01f, - 0.001f, - 0.0001f, - 0.00001f, - 0.000001f, - 0.0000001f, - 0.00000001f, - 0.000000001f, - 0.0000000001f, - 0.00000000001f, - 0.000000000001f, - 0.0000000000001f, - 0.00000000000001f, - 0.000000000000001f +const double fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug + 0.0, + 0.1, + 0.01, + 0.001, + 0.0001, + 0.00001, + 0.000001, + 0.0000001, + 0.00000001, + 0.000000001, + 0.0000000001, + 0.00000000001, + 0.000000000001, + 0.0000000000001, + 0.00000000000001, + 0.000000000000001 }; @@ -178,6 +179,9 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* unsigned int cur = 0; uint64_t value = 0; + if ( *in < '0' || *in > '9' ) + throw std::invalid_argument(std::string("The string \"") + in + "\" cannot be converted into a value."); + bool running = true; while ( running ) { @@ -187,7 +191,7 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* const uint64_t new_value = ( value * 10 ) + ( *in - '0' ); if (new_value < value) /* numeric overflow, we rely on you */ - return value; + throw std::overflow_error(std::string("Converting the string \"") + in + "\" into a value resulted in overflow."); value = new_value; @@ -223,7 +227,7 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* // If you find any bugs, please send them to me, niko (at) irrlicht3d.org. // ------------------------------------------------------------------------------------ template <typename Real> -inline const char* fast_atoreal_move( const char* c, Real& out) +inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma = true) { Real f; @@ -233,7 +237,7 @@ inline const char* fast_atoreal_move( const char* c, Real& out) } f = static_cast<Real>( strtoul10_64 ( c, &c) ); - if (*c == '.' || (c[0] == ',' && c[1] >= '0' && c[1] <= '9')) // allow for commas, too + if (*c == '.' || (check_comma && c[0] == ',' && c[1] >= '0' && c[1] <= '9')) // allow for commas, too { ++c; @@ -269,7 +273,7 @@ inline const char* fast_atoreal_move( const char* c, Real& out) if (einv) { exp = -exp; } - f *= pow(static_cast<Real>(10.0f), exp); + f *= pow(static_cast<Real>(10.0), exp); } if (inv) { diff --git a/src/3rdparty/assimp/code/irrXMLWrapper.h b/src/3rdparty/assimp/code/irrXMLWrapper.h index ab37f447c..b06b426f8 100644 --- a/src/3rdparty/assimp/code/irrXMLWrapper.h +++ b/src/3rdparty/assimp/code/irrXMLWrapper.h @@ -81,12 +81,22 @@ public: // Map the buffer into memory and convert it to UTF8. IrrXML provides its // own conversion, which is merely a cast from uintNN_t to uint8_t. Thus, // it is not suitable for our purposes and we have to do it BEFORE IrrXML - // gets the buffer. Sadly, this forces as to map the whole file into + // gets the buffer. Sadly, this forces us to map the whole file into // memory. data.resize(stream->FileSize()); stream->Read(&data[0],data.size(),1); + // Remove null characters from the input sequence otherwise the parsing will utterly fail + unsigned int size = 0; + unsigned int size_max = data.size(); + for(unsigned int i = 0; i < size_max; i++) { + if(data[i] != '\0') { + data[size++] = data[i]; + } + } + data.resize(size); + BaseImporter::ConvertToUTF8(data); } |