diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2014-05-26 10:35:32 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-06-04 10:09:11 +0200 |
commit | 1cb807d440cc0d434bfd02fd0c699447b788b8ba (patch) | |
tree | f28f64fba6ebb30449c3301a75bba2b233b1f34e /src/3rdparty/assimp | |
parent | a45b8308ada361872502a678a12f08cff1760c64 (diff) | |
download | qt3d-1cb807d440cc0d434bfd02fd0c699447b788b8ba.tar.gz |
Upgrade to Assimp 3.1
https://github.com/assimp/assimp/releases/tag/v3.1
This commit imports assimp 3.1, including CHANGES, CREDITS, LICENSE, README,
Readme.md, revision.h and code, contrib, include directories. contrib/zlib
was excluded.
assimp.pri was also updated.
Uses zlib from system or qt instead of contrib/zlib.
Task-number: QTBUG-39251
Change-Id: Ia0b446dcd9bc867d65897b9e2b157f6544ccaeac
Reviewed-by: Liang Qi <liang.qi@digia.com>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/3rdparty/assimp')
247 files changed, 27793 insertions, 20160 deletions
diff --git a/src/3rdparty/assimp/CREDITS b/src/3rdparty/assimp/CREDITS index 3678f130f..33f4acce4 100644 --- a/src/3rdparty/assimp/CREDITS +++ b/src/3rdparty/assimp/CREDITS @@ -135,4 +135,13 @@ Several LWO and LWS fixes (pivoting). GCC/Linux fixes for the SimpleOpenGL sample. - Brian Miller -Bugfix for a compiler fix for iOS on arm.
\ No newline at end of file +Bugfix for a compiler fix for iOS on arm. + +- Séverin Lemaignan +Rewrite of PyAssimp, distutils and Python3 support + +- albert-wang +Bugfixes for the collada parser + +- Ya ping Jin +Bugfixes for uv-tanget calculation. diff --git a/src/3rdparty/assimp/README b/src/3rdparty/assimp/README index b92db54ef..24619ab94 100644 --- a/src/3rdparty/assimp/README +++ b/src/3rdparty/assimp/README @@ -1,130 +1 @@ - -======================================================================== -Open Asset Import Library (assimp) README -======================================================================== - - -Table of Contents - - 1. Overview - 1.1 Supported file formats - 1.2 File structure - 2. Build the library - 3. Where to get help - 4. License - - ------------------------------- -1. Overview ------------------------------- - -Open Asset Import Library is a Open Source library designed to load various 3d -file formats and convert them into a shared, in-memory format. It supports more -than 30 file formats (basically, it is like DevIL for 3D models). It also -supports exporting, but the number of export formats is lower. - -Its short name is 'assimp', which is an unintended joke (the abbreviation is -derived from 'Asset Importer'). - -Note: this README refers to the file structure used by release packages, which -differs in some points from the development trunk. - ----------------- - 1.1 Supported file formats ----------------- - -The library provides importers for a lot of file formats, including: - - 3DS - - BLEND - - DAE (Collada) - - IFC-STEP - - ASE - - DXF - - HMP - - MD2 - - MD3 - - MD5 - - MDC - - MDL - - NFF - - PLY - - STL - - X - - OBJ - - SMD - - LWO - - LXO - - LWS - - XML - - TER - - AC3D - - MS3D - -Exporters include: - - DAE (Collada) - - STL - - OBJ - - .. See http://assimp.sourceforge.net/main_features_formats.html for - a more exhaustive list. - - ----------------- -1.2 Repository structure ----------------- - -Open Asset Import Library is implemented in C++ (but provides both a C and a -C++ish interface). The directory structure is: - - /bin Folder for binaries, only used on Windows - /code Source code - /contrib Third-party libraries - /doc Documentation (doxysource and pre-compiled docs) - /include Public header C and C++ header files. - /lib Static library location for Windows. - /obj Object file location for Windows. - /port Ports to other languages and scripts to maintain those. - /test Unit- and regression tests, test suite of models. - /tools Tools (viewer, command line `assimp`). - /samples A small number of samples to illustrate possible - use cases for Assimp. - /workspaces Build enviroments for vc,xcode,... (deprecated, - CMake has superseeded all legacy build options!) - - ------------------------------- -2. Build the library ------------------------------- - -Take a look into the INSTALL file. - - ------------------------------- -3. Where to get help ------------------------------- - -For more information, visit http://assimp.sourceforge.net/. Or have a look into -the ./doc- folder, which contains the official documentation in HTML format. -(CHMs for Windows are included in some release packages and should be located -right here in the root folder). - -If the documentation doesn't solve your problems, try our forums at SF.net -> Open Discussion: http://sourceforge.net/projects/assimp/forums/forum/817653) -> General Help: http://sourceforge.net/projects/assimp/forums/forum/817654 - -For development stuff, there is also a mailing list, assimp-discussions - subscribe: https://lists.sourceforge.net/lists/listinfo/assimp-discussions - - ------------------------------- -4. License ------------------------------- - -The license of the Asset Import Library is based on the modified, 3-clause BSD- -License, which is a very liberal license. An _informal_ summary is: do whatever -you want, but include Assimp's license text with your product - and don't sue -us if our code doesn't work. - -Note that, unlike LGPLed code, you may link statically to Assimp. -For the formal details, see the LICENSE file. - +See Readme.md diff --git a/src/3rdparty/assimp/Readme.md b/src/3rdparty/assimp/Readme.md new file mode 100644 index 000000000..380e4386f --- /dev/null +++ b/src/3rdparty/assimp/Readme.md @@ -0,0 +1,120 @@ +Open Asset Import Library (assimp) +======== + +Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a single, in-memory format__. It supports more than __30 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials_ and many more. + +Its short name under which it is commonly known is __assimp__. + +This is the development trunk of assimp containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories. According to [Travis-CI] (https://travis-ci.org/), the current build status of the trunk is [![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp) + +#### Supported file formats #### + +The library provides importers for a lot of file formats, including: + +- 3DS +- BLEND (Blender 3D) +- DAE/Collada +- FBX +- IFC-STEP +- ASE +- DXF +- HMP +- MD2 +- MD3 +- MD5 +- MDC +- MDL +- NFF +- PLY +- STL +- X +- OBJ +- SMD +- LWO +- LXO +- LWS +- TER +- AC3D +- MS3D +- COB +- Q3BSP +- XGL +- CSM +- BVH +- B3D +- NDO +- Ogre XML +- Q3D + +Additionally, the following formats are also supported, but not part of the core library as they depend on proprietary libraries. + +- C4D (https://github.com/acgessler/assimp-cinema4d) + +Exporters include: + +- DAE (Collada) +- STL +- OBJ +- PLY + +See [the full list here](http://assimp.sourceforge.net/main_features_formats.html). + + + +#### Repository structure #### + + +Open Asset Import Library is implemented in C++ (but provides both a C and a +C++ish interface). The directory structure is: + + /bin Folder for binaries, only used on Windows + /code Source code + /contrib Third-party libraries + /doc Documentation (doxysource and pre-compiled docs) + /include Public header C and C++ header files + /lib Static library location for Windows + /obj Object file location for Windows + /scripts Scripts used to generate the loading code for some formats + /port Ports to other languages and scripts to maintain those. + /test Unit- and regression tests, test suite of models + /tools Tools (viewer, command line `assimp`) + /samples A small number of samples to illustrate possible + use cases for Assimp + /workspaces Build enviroments for vc,xcode,... (deprecated, + CMake has superseeded all legacy build options!) + + + +### Building ### + + +Take a look into the `INSTALL` file. Our build system is CMake, if you already used CMake before there is a good chance you know what to do. + + +### Where to get help ### + + +For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format. +(CHMs for Windows are included in some release packages and should be located right here in the root folder). + +If the documentation doesn't solve your problems, +[try our forums at SF.net](http://sourceforge.net/p/assimp/discussion/817654) or ask on +[StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest). + +For development discussions, there is also a mailing list, _assimp-discussions_ + [(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions) + +### Contributing ### + +Contributions to assimp are highly appreciated. The easiest way to get involved is to submit +a pull request with your changes against the main repository's `master` branch. + + +### License ### + +Our license is based on the modified, __3-clause BSD__-License, which is very liberal. + +An _informal_ summary is: do whatever you want, but include Assimp's license text with your product - +and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp. +For the legal details, see the `LICENSE` file. + diff --git a/src/3rdparty/assimp/assimp.pri b/src/3rdparty/assimp/assimp.pri index 91b68ab90..af2432c38 100644 --- a/src/3rdparty/assimp/assimp.pri +++ b/src/3rdparty/assimp/assimp.pri @@ -8,6 +8,15 @@ CONFIG += exceptions win32:DEFINES+=_CRT_SECURE_NO_WARNINGS +contains(QT_CONFIG, system-zlib) { + unix|mingw: LIBS += -lz + else: LIBS += zdll.lib +} else { + INCLUDEPATH += $$[QT_INSTALL_HEADERS/get]/QtZlib +} + +DEFINES += ASSIMP_BUILD_NO_OWN_ZLIB + VPATH += \ $$PWD \ $$PWD/code \ @@ -16,7 +25,6 @@ VPATH += \ $$PWD/contrib/ConvertUTF \ $$PWD/contrib/irrXML \ $$PWD/contrib/unzip \ - $$PWD/contrib/zlib INCLUDEPATH += \ $$PWD \ @@ -25,7 +33,6 @@ INCLUDEPATH += \ $$PWD/include \ $$PWD/include/assimp/Compiler \ $$PWD/contrib/ConvertUTF \ - $$PWD/contrib/zlib \ $$PWD/contrib/irrXML \ $$PWD/contrib/poly2tri/poly2tri \ $$PWD/contrib/clipper \ @@ -42,6 +49,8 @@ HEADERS += revision.h \ code/AssimpPCH.h \ code/B3DImporter.h \ code/BaseImporter.h \ + code/Bitmap.h \ + code/BlenderBMesh.h \ code/BaseProcess.h \ code/BlenderDNA.h \ code/BlenderIntermediate.h \ @@ -49,6 +58,7 @@ HEADERS += revision.h \ code/BlenderModifier.h \ code/BlenderScene.h \ code/BlenderSceneGen.h \ + code/BlenderTessellator.h \ code/BlobIOSystem.h \ code/BVHLoader.h \ code/ByteSwap.h \ @@ -199,17 +209,6 @@ HEADERS += revision.h \ contrib/unzip/crypt.h \ contrib/unzip/ioapi.h \ contrib/unzip/unzip.h \ - contrib/zlib/crc32.h \ - contrib/zlib/deflate.h \ - contrib/zlib/inffast.h \ - contrib/zlib/inffixed.h \ - contrib/zlib/inflate.h \ - contrib/zlib/inftrees.h \ - contrib/zlib/trees.h \ - contrib/zlib/zconf.h \ - contrib/zlib/zconf.in.h \ - contrib/zlib/zlib.h \ - contrib/zlib/zutil.h \ include/assimp/ai_assert.h \ include/assimp/anim.h \ include/assimp/camera.h \ @@ -273,7 +272,21 @@ HEADERS += revision.h \ include/assimp/matrix4x4.inl \ include/assimp/material.inl \ code/SmoothingGroups.inl \ - code/BlenderDNA.inl + code/BlenderDNA.inl \ + code/FBXConverter.h \ + code/FBXDocument.h \ + code/FBXDocumentUtil.h \ + code/FBXImporter.h \ + code/FBXImportSettings.h \ + code/FBXParser.h \ + code/FBXProperties.h \ + code/FBXTokenizer.h \ + code/FBXUtil.h \ + code/OgreImporter.h \ + code/OgreParsingUtils.h \ + code/FBXCompileConfig.h \ + code/STEPFileEncoding.h \ + include/assimp/metadata.h SOURCES += code/3DSConverter.cpp \ code/3DSLoader.cpp \ @@ -285,11 +298,14 @@ SOURCES += code/3DSConverter.cpp \ code/AssimpPCH.cpp \ code/B3DImporter.cpp \ code/BaseImporter.cpp \ + code/Bitmap.cpp \ + code/BlenderBMesh.cpp \ code/BaseProcess.cpp \ code/BlenderDNA.cpp \ code/BlenderLoader.cpp \ code/BlenderModifier.cpp \ code/BlenderScene.cpp \ + code/BlenderTessellator.cpp \ code/BVHLoader.cpp \ code/CalcTangentsProcess.cpp \ code/COBLoader.cpp \ @@ -399,17 +415,28 @@ SOURCES += code/3DSConverter.cpp \ contrib/irrXML/irrXML.cpp \ contrib/unzip/ioapi.c \ contrib/unzip/unzip.c \ - contrib/zlib/adler32.c \ - contrib/zlib/compress.c \ - contrib/zlib/crc32.c \ - contrib/zlib/deflate.c \ - contrib/zlib/inffast.c \ - contrib/zlib/inflate.c \ - contrib/zlib/inftrees.c \ - contrib/zlib/trees.c \ - contrib/zlib/zutil.c \ contrib/poly2tri/poly2tri/common/shapes.cc \ contrib/poly2tri/poly2tri/sweep/advancing_front.cc \ contrib/poly2tri/poly2tri/sweep/cdt.cc \ contrib/poly2tri/poly2tri/sweep/sweep.cc \ - contrib/poly2tri/poly2tri/sweep/sweep_context.cc + contrib/poly2tri/poly2tri/sweep/sweep_context.cc \ + code/FBXAnimation.cpp \ + code/FBXBinaryTokenizer.cpp \ + code/FBXDeformer.cpp \ + code/FBXDocument.cpp \ + code/FBXDocumentUtil.cpp \ + code/FBXImporter.cpp \ + code/FBXMaterial.cpp \ + code/FBXMeshGeometry.cpp \ + code/FBXModel.cpp \ + code/FBXNodeAttribute.cpp \ + code/FBXParser.cpp \ + code/FBXProperties.cpp \ + code/FBXTokenizer.cpp \ + code/FBXUtil.cpp \ + code/IFCBoolean.cpp \ + code/IFCOpenings.cpp \ + code/FBXConverter.cpp \ + code/STEPFileEncoding.cpp + + 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); } diff --git a/src/3rdparty/assimp/contrib/clipper/clipper.cpp b/src/3rdparty/assimp/contrib/clipper/clipper.cpp index aa79928b9..2b209da69 100644 --- a/src/3rdparty/assimp/contrib/clipper/clipper.cpp +++ b/src/3rdparty/assimp/contrib/clipper/clipper.cpp @@ -1,10 +1,10 @@ /******************************************************************************* * * * Author : Angus Johnson * -* Version : 4.6.3 * -* Date : 11 November 2011 * +* Version : 4.8.8 * +* Date : 30 August 2012 * * Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2011 * +* Copyright : Angus Johnson 2010-2012 * * * * License: * * Use, modification & distribution is subject to Boost Software License Ver 1. * @@ -49,11 +49,10 @@ namespace ClipperLib { -static long64 const loRange = 1518500249; //sqrt(2^63 -1)/2 -static long64 const hiRange = 6521908912666391106LL; //sqrt(2^127 -1)/2 +static long64 const loRange = 0x3FFFFFFF; +static long64 const hiRange = 0x3FFFFFFFFFFFFFFFLL; static double const pi = 3.141592653589793238; enum Direction { dRightToLeft, dLeftToRight }; -enum RangeTest { rtLo, rtHi, rtError }; #define HORIZONTAL (-1.0E+40) #define TOLERANCE (1.0e-20) @@ -62,7 +61,7 @@ enum RangeTest { rtLo, rtHi, rtError }; inline long64 Abs(long64 val) { - if (val < 0) return -val; else return val; + return val < 0 ? -val : val; } //------------------------------------------------------------------------------ @@ -80,43 +79,47 @@ class Int128 Int128(long64 _lo = 0) { - hi = 0; - if (_lo < 0) { - lo = -_lo; - Negate(*this); - } else - lo = _lo; + lo = _lo; + if (lo < 0) hi = -1; else hi = 0; } Int128(const Int128 &val): hi(val.hi), lo(val.lo){} long64 operator = (const long64 &val) { - hi = 0; - lo = Abs(val); - if (val < 0) Negate(*this); + lo = val; + if (lo < 0) hi = -1; else hi = 0; return val; } bool operator == (const Int128 &val) const {return (hi == val.hi && lo == val.lo);} - bool operator != (const Int128 &val) const { return !(*this == val);} + bool operator != (const Int128 &val) const + { return !(*this == val);} bool operator > (const Int128 &val) const { - if (hi > val.hi) return true; - else if (hi < val.hi) return false; - else return ulong64(lo) > ulong64(val.lo); + if (hi != val.hi) + return hi > val.hi; + else + return lo > val.lo; } bool operator < (const Int128 &val) const { - if (hi < val.hi) return true; - else if (hi > val.hi) return false; - else return ulong64(lo) < ulong64(val.lo); + if (hi != val.hi) + return hi < val.hi; + else + return lo < val.lo; } + bool operator >= (const Int128 &val) const + { return !(*this < val);} + + bool operator <= (const Int128 &val) const + { return !(*this > val);} + Int128& operator += (const Int128 &rhs) { hi += rhs.hi; @@ -140,14 +143,28 @@ class Int128 return *this; } + //Int128 operator -() const + //{ + // Int128 result(*this); + // if (result.lo == 0) { + // if (result.hi != 0) result.hi = -1; + // } + // else { + // result.lo = -result.lo; + // result.hi = ~result.hi; + // } + // return result; + //} + Int128 operator - (const Int128 &rhs) const { Int128 result(*this); - result-= rhs; + result -= rhs; return result; } - Int128 operator * (const Int128 &rhs) const { + Int128 operator * (const Int128 &rhs) const + { if ( !(hi == 0 || hi == -1) || !(rhs.hi == 0 || rhs.hi == -1)) throw "Int128 operator*: overflow error"; bool negate = (hi < 0) != (rhs.hi < 0); @@ -225,25 +242,25 @@ class Int128 } //for bug testing ... - std::string AsString() const - { - std::string result; - unsigned char r = 0; - Int128 tmp(0), val(*this); - if (hi < 0) Negate(val); - result.resize(50); - std::string::size_type i = result.size() -1; - while (val.hi != 0 || val.lo != 0) - { - Div10(val, tmp, r); - result[i--] = char('0' + r); - val = tmp; - } - if (hi < 0) result[i--] = '-'; - result.erase(0,i+1); - if (result.size() == 0) result = "0"; - return result; - } + //std::string AsString() const + //{ + // std::string result; + // unsigned char r = 0; + // Int128 tmp(0), val(*this); + // if (hi < 0) Negate(val); + // result.resize(50); + // std::string::size_type i = result.size() -1; + // while (val.hi != 0 || val.lo != 0) + // { + // Div10(val, tmp, r); + // result[i--] = char('0' + r); + // val = tmp; + // } + // if (hi < 0) result[i--] = '-'; + // result.erase(0,i+1); + // if (result.size() == 0) result = "0"; + // return result; + //} private: long64 hi; @@ -251,79 +268,70 @@ private: static void Negate(Int128 &val) { - if (val.lo == 0) - { - if( val.hi == 0) return; - val.lo = ~val.lo; - val.hi = ~val.hi +1; + if (val.lo == 0) { + if (val.hi != 0) val.hi = -val.hi;; } - else - { - val.lo = ~val.lo +1; + else { + val.lo = -val.lo; val.hi = ~val.hi; } } //debugging only ... - void Div10(const Int128 val, Int128& result, unsigned char & remainder) const - { - remainder = 0; - result = 0; - for (int i = 63; i >= 0; --i) - { - if ((val.hi & ((long64)1 << i)) != 0) - remainder = char((remainder * 2) + 1); else - remainder *= char(2); - if (remainder >= 10) - { - result.hi += ((long64)1 << i); - remainder -= char(10); - } - } - for (int i = 63; i >= 0; --i) - { - if ((val.lo & ((long64)1 << i)) != 0) - remainder = char((remainder * 2) + 1); else - remainder *= char(2); - if (remainder >= 10) - { - result.lo += ((long64)1 << i); - remainder -= char(10); - } - } - } + //void Div10(const Int128 val, Int128& result, unsigned char & remainder) const + //{ + // remainder = 0; + // result = 0; + // for (int i = 63; i >= 0; --i) + // { + // if ((val.hi & ((long64)1 << i)) != 0) + // remainder = char((remainder * 2) + 1); else + // remainder *= char(2); + // if (remainder >= 10) + // { + // result.hi += ((long64)1 << i); + // remainder -= char(10); + // } + // } + // for (int i = 63; i >= 0; --i) + // { + // if ((val.lo & ((long64)1 << i)) != 0) + // remainder = char((remainder * 2) + 1); else + // remainder *= char(2); + // if (remainder >= 10) + // { + // result.lo += ((long64)1 << i); + // remainder -= char(10); + // } + // } + //} }; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -RangeTest TestRange(const Polygon &pts) +bool FullRangeNeeded(const Polygon &pts) { - RangeTest result = rtLo; + bool result = false; for (Polygon::size_type i = 0; i < pts.size(); ++i) { if (Abs(pts[i].X) > hiRange || Abs(pts[i].Y) > hiRange) - return rtError; + throw "Coordinate exceeds range bounds."; else if (Abs(pts[i].X) > loRange || Abs(pts[i].Y) > loRange) - result = rtHi; + result = true; } return result; } //------------------------------------------------------------------------------ - + bool Orientation(const Polygon &poly) { int highI = (int)poly.size() -1; if (highI < 2) return false; - bool UseFullInt64Range = false; int j = 0, jplus, jminus; for (int i = 0; i <= highI; ++i) { - if (Abs(poly[i].X) > hiRange || Abs(poly[i].Y) > hiRange) - throw "Coordinate exceeds range bounds."; - if (Abs(poly[i].X) > loRange || Abs(poly[i].Y) > loRange) - UseFullInt64Range = true; if (poly[i].Y < poly[j].Y) continue; if ((poly[i].Y > poly[j].Y || poly[i].X < poly[j].X)) j = i; }; @@ -339,21 +347,30 @@ bool Orientation(const Polygon &poly) vec2.X = poly[jplus].X - poly[j].X; vec2.Y = poly[jplus].Y - poly[j].Y; - if (UseFullInt64Range) + if (Abs(vec1.X) > loRange || Abs(vec1.Y) > loRange || + Abs(vec2.X) > loRange || Abs(vec2.Y) > loRange) { + if (Abs(vec1.X) > hiRange || Abs(vec1.Y) > hiRange || + Abs(vec2.X) > hiRange || Abs(vec2.Y) > hiRange) + throw "Coordinate exceeds range bounds."; Int128 cross = Int128(vec1.X) * Int128(vec2.Y) - Int128(vec2.X) * Int128(vec1.Y); - return cross > 0; + return cross >= 0; } else - { - return (vec1.X * vec2.Y - vec2.X * vec1.Y) > 0; - } + return (vec1.X * vec2.Y - vec2.X * vec1.Y) >= 0; +} +//------------------------------------------------------------------------------ + +inline bool PointsEqual( const IntPoint &pt1, const IntPoint &pt2) +{ + return ( pt1.X == pt2.X && pt1.Y == pt2.Y ); } //------------------------------------------------------------------------------ bool Orientation(OutRec *outRec, bool UseFullInt64Range) { + //first make sure bottomPt is correctly assigned ... OutPt *opBottom = outRec->pts, *op = outRec->pts->next; while (op != outRec->pts) { @@ -364,28 +381,28 @@ bool Orientation(OutRec *outRec, bool UseFullInt64Range) } op = op->next; } + outRec->bottomPt = opBottom; + opBottom->idx = outRec->idx; - IntPoint vec1, vec2; - vec1.X = op->pt.X - op->prev->pt.X; - vec1.Y = op->pt.Y - op->prev->pt.Y; - vec2.X = op->next->pt.X - op->pt.X; - vec2.Y = op->next->pt.Y - op->pt.Y; + op = opBottom; + //find vertices either side of bottomPt (skipping duplicate points) .... + OutPt *opPrev = op->prev; + OutPt *opNext = op->next; + while (op != opPrev && PointsEqual(op->pt, opPrev->pt)) + opPrev = opPrev->prev; + while (op != opNext && PointsEqual(op->pt, opNext->pt)) + opNext = opNext->next; + + IntPoint ip1, ip2; + ip1.X = op->pt.X - opPrev->pt.X; + ip1.Y = op->pt.Y - opPrev->pt.Y; + ip2.X = opNext->pt.X - op->pt.X; + ip2.Y = opNext->pt.Y - op->pt.Y; if (UseFullInt64Range) - { - Int128 cross = Int128(vec1.X) * Int128(vec2.Y) - Int128(vec2.X) * Int128(vec1.Y); - return cross > 0; - } + return Int128(ip1.X) * Int128(ip2.Y) - Int128(ip2.X) * Int128(ip1.Y) >= 0; else - { - return (vec1.X * vec2.Y - vec2.X * vec1.Y) > 0; - } -} -//------------------------------------------------------------------------------ - -inline bool PointsEqual( const IntPoint &pt1, const IntPoint &pt2) -{ - return ( pt1.X == pt2.X && pt1.Y == pt2.Y ); + return (ip1.X * ip2.Y - ip2.X * ip1.Y) >= 0; } //------------------------------------------------------------------------------ @@ -393,21 +410,9 @@ double Area(const Polygon &poly) { int highI = (int)poly.size() -1; if (highI < 2) return 0; - bool UseFullInt64Range; - RangeTest rt = TestRange(poly); - switch (rt) { - case rtLo: - UseFullInt64Range = false; - break; - case rtHi: - UseFullInt64Range = true; - break; - default: - throw "Coordinate exceeds range bounds."; - } - if (UseFullInt64Range) { - Int128 a(0); + if (FullRangeNeeded(poly)) { + Int128 a; a = (Int128(poly[highI].X) * Int128(poly[0].Y)) - Int128(poly[0].X) * Int128(poly[highI].Y); for (int i = 0; i < highI; ++i) @@ -426,6 +431,30 @@ double Area(const Polygon &poly) } //------------------------------------------------------------------------------ +double Area(const OutRec &outRec, bool UseFullInt64Range) +{ + OutPt *op = outRec.pts; + if (UseFullInt64Range) { + Int128 a(0); + do { + a += (Int128(op->prev->pt.X) * Int128(op->pt.Y)) - + Int128(op->pt.X) * Int128(op->prev->pt.Y); + op = op->next; + } while (op != outRec.pts); + return a.AsDouble() / 2; + } + else + { + double a = 0; + do { + a += (op->prev->pt.X * op->pt.Y) - (op->pt.X * op->prev->pt.Y); + op = op->next; + } while (op != outRec.pts); + return a/2; + } +} +//------------------------------------------------------------------------------ + bool PointIsVertex(const IntPoint &pt, OutPt *pp) { OutPt *pp2 = pp; @@ -473,9 +502,7 @@ bool PointInPolygon(const IntPoint &pt, OutPt *pp, bool UseFullInt64Range) bool SlopesEqual(TEdge &e1, TEdge &e2, bool UseFullInt64Range) { - if (e1.ybot == e1.ytop) return (e2.ybot == e2.ytop); - else if (e1.xbot == e1.xtop) return (e2.xbot == e2.xtop); - else if (UseFullInt64Range) + if (UseFullInt64Range) return Int128(e1.ytop - e1.ybot) * Int128(e2.xtop - e2.xbot) == Int128(e1.xtop - e1.xbot) * Int128(e2.ytop - e2.ybot); else return (e1.ytop - e1.ybot)*(e2.xtop - e2.xbot) == @@ -486,9 +513,7 @@ bool SlopesEqual(TEdge &e1, TEdge &e2, bool UseFullInt64Range) bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3, bool UseFullInt64Range) { - if (pt1.Y == pt2.Y) return (pt2.Y == pt3.Y); - else if (pt1.X == pt2.X) return (pt2.X == pt3.X); - else if (UseFullInt64Range) + if (UseFullInt64Range) return Int128(pt1.Y-pt2.Y) * Int128(pt2.X-pt3.X) == Int128(pt1.X-pt2.X) * Int128(pt2.Y-pt3.Y); else return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y); @@ -498,9 +523,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range) { - if (pt1.Y == pt2.Y) return (pt3.Y == pt4.Y); - else if (pt1.X == pt2.X) return (pt3.X == pt4.X); - else if (UseFullInt64Range) + if (UseFullInt64Range) return Int128(pt1.Y-pt2.Y) * Int128(pt3.X-pt4.X) == Int128(pt1.X-pt2.X) * Int128(pt3.Y-pt4.Y); else return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y); @@ -509,17 +532,15 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, double GetDx(const IntPoint pt1, const IntPoint pt2) { - if (pt1.Y == pt2.Y) return HORIZONTAL; - else return - (double)(pt2.X - pt1.X) / (double)(pt2.Y - pt1.Y); + return (pt1.Y == pt2.Y) ? + HORIZONTAL : (double)(pt2.X - pt1.X) / (double)(pt2.Y - pt1.Y); } //--------------------------------------------------------------------------- void SetDx(TEdge &e) { if (e.ybot == e.ytop) e.dx = HORIZONTAL; - else e.dx = - (double)(e.xtop - e.xbot) / (double)(e.ytop - e.ybot); + else e.dx = (double)(e.xtop - e.xbot) / (double)(e.ytop - e.ybot); } //--------------------------------------------------------------------------- @@ -541,15 +562,15 @@ void SwapPolyIndexes(TEdge &edge1, TEdge &edge2) inline long64 Round(double val) { - if ((val < 0)) return static_cast<long64>(val - 0.5); - else return static_cast<long64>(val + 0.5); + return (val < 0) ? + static_cast<long64>(val - 0.5) : static_cast<long64>(val + 0.5); } //------------------------------------------------------------------------------ long64 TopX(TEdge &edge, const long64 currentY) { - if( currentY == edge.ytop ) return edge.xtop; - return edge.xbot + Round(edge.dx *(currentY - edge.ybot)); + return ( currentY == edge.ytop ) ? + edge.xtop : edge.xbot + Round(edge.dx *(currentY - edge.ybot)); } //------------------------------------------------------------------------------ @@ -709,17 +730,60 @@ bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a, } //------------------------------------------------------------------------------ -OutPt* PolygonBottom(OutPt* pp) +bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2) { + OutPt *p = btmPt1->prev; + while (PointsEqual(p->pt, btmPt1->pt) && (p != btmPt1)) p = p->prev; + double dx1p = std::fabs(GetDx(btmPt1->pt, p->pt)); + p = btmPt1->next; + while (PointsEqual(p->pt, btmPt1->pt) && (p != btmPt1)) p = p->next; + double dx1n = std::fabs(GetDx(btmPt1->pt, p->pt)); + + p = btmPt2->prev; + while (PointsEqual(p->pt, btmPt2->pt) && (p != btmPt2)) p = p->prev; + double dx2p = std::fabs(GetDx(btmPt2->pt, p->pt)); + p = btmPt2->next; + while (PointsEqual(p->pt, btmPt2->pt) && (p != btmPt2)) p = p->next; + double dx2n = std::fabs(GetDx(btmPt2->pt, p->pt)); + return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); +} +//------------------------------------------------------------------------------ + +OutPt* GetBottomPt(OutPt *pp) +{ + OutPt* dups = 0; OutPt* p = pp->next; - OutPt* result = pp; while (p != pp) { - if (p->pt.Y > result->pt.Y) result = p; - else if (p->pt.Y == result->pt.Y && p->pt.X < result->pt.X) result = p; + if (p->pt.Y > pp->pt.Y) + { + pp = p; + dups = 0; + } + else if (p->pt.Y == pp->pt.Y && p->pt.X <= pp->pt.X) + { + if (p->pt.X < pp->pt.X) + { + dups = 0; + pp = p; + } else + { + if (p->next != pp && p->prev != pp) dups = p; + } + } p = p->next; } - return result; + if (dups) + { + //there appears to be at least 2 vertices at bottomPt so ... + while (dups != p) + { + if (!FirstIsBottomPt(p, dups)) pp = dups; + dups = dups->next; + while (!PointsEqual(dups->pt, pp->pt)) dups = dups->next; + } + } + return pp; } //------------------------------------------------------------------------------ @@ -805,11 +869,9 @@ bool ClipperBase::AddPolygon( const Polygon &pg, PolyType polyType) { if (Abs(pg[i].X) > maxVal || Abs(pg[i].Y) > maxVal) { - if (m_UseFullRange) + if (Abs(pg[i].X) > hiRange || Abs(pg[i].Y) > hiRange) throw "Coordinate exceeds range bounds"; maxVal = hiRange; - if (Abs(pg[i].X) > maxVal || Abs(pg[i].Y) > maxVal) - throw "Coordinate exceeds range bounds"; m_UseFullRange = true; } @@ -823,7 +885,7 @@ bool ClipperBase::AddPolygon( const Polygon &pg, PolyType polyType) if (j < 2) return false; len = j+1; - for (;;) + while (len > 2) { //nb: test for point equality before testing slopes ... if (PointsEqual(p[j], p[0])) j--; @@ -836,9 +898,8 @@ bool ClipperBase::AddPolygon( const Polygon &pg, PolyType polyType) for (int i = 2; i <= j; ++i) p[i-1] = p[i]; j--; } - //exit loop if nothing is changed or there are too few vertices ... - if (j == len-1 || j < 2) break; - len = j +1; + else break; + len--; } if (len < 3) return false; @@ -961,9 +1022,9 @@ TEdge* ClipperBase::AddBoundsToLML(TEdge *e) bool ClipperBase::AddPolygons(const Polygons &ppg, PolyType polyType) { - bool result = true; + bool result = false; for (Polygons::size_type i = 0; i < ppg.size(); ++i) - if (AddPolygon(ppg[i], polyType)) result = false; + if (AddPolygon(ppg[i], polyType)) result = true; return result; } //------------------------------------------------------------------------------ @@ -1116,6 +1177,7 @@ void Clipper::Reset() m_Scanbeam = 0; m_ActiveEdges = 0; m_SortedEdges = 0; + DisposeAllPolyPts(); LocalMinima* lm = m_MinimaList; while (lm) { @@ -1165,7 +1227,7 @@ bool PolySort(OutRec *or1, OutRec *or2) { if (or1->pts != or2->pts) { - if (or1->pts) return true; else return false; + return or1->pts ? true : false; } else return false; } @@ -1179,8 +1241,7 @@ bool PolySort(OutRec *or1, OutRec *or2) int result = i1 - i2; if (result == 0 && (or1->isHole != or2->isHole)) { - if (or1->isHole) return false; - else return true; + return or1->isHole ? false : true; } else return result < 0; } @@ -1250,6 +1311,11 @@ bool Clipper::ExecuteInternal(bool fixHoleLinkages) FixupOutPolygon(*outRec); if (!outRec->pts) continue; if (outRec->isHole && fixHoleLinkages) FixHoleLinkage(outRec); + + if (outRec->bottomPt == outRec->bottomFlag && + (Orientation(outRec, m_UseFullRange) != (Area(*outRec, m_UseFullRange) > 0))) + DisposeBottomPt(*outRec); + if (outRec->isHole == (m_ReverseOutput ^ Orientation(outRec, m_UseFullRange))) ReversePolyPtLinks(*outRec->pts); @@ -1310,10 +1376,10 @@ void Clipper::DisposeAllPolyPts(){ } //------------------------------------------------------------------------------ -void Clipper::DisposeOutRec(PolyOutList::size_type index, bool ignorePts) +void Clipper::DisposeOutRec(PolyOutList::size_type index) { OutRec *outRec = m_PolyOuts[index]; - if (!ignorePts && outRec->pts) DisposeOutPts(outRec->pts); + if (outRec->pts) DisposeOutPts(outRec->pts); delete outRec; m_PolyOuts[index] = 0; } @@ -1476,32 +1542,49 @@ bool Clipper::IsContributing(const TEdge& edge) const void Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) { + TEdge *e, *prevE; if( NEAR_EQUAL(e2->dx, HORIZONTAL) || ( e1->dx > e2->dx ) ) { - AddOutPt( e1, e2, pt ); + AddOutPt( e1, pt ); e2->outIdx = e1->outIdx; e1->side = esLeft; e2->side = esRight; + e = e1; + if (e->prevInAEL == e2) + prevE = e2->prevInAEL; + else + prevE = e->prevInAEL; } else { - AddOutPt( e2, e1, pt ); + AddOutPt( e2, pt ); e1->outIdx = e2->outIdx; e1->side = esRight; e2->side = esLeft; + e = e2; + if (e->prevInAEL == e1) + prevE = e1->prevInAEL; + else + prevE = e->prevInAEL; } + if (prevE && prevE->outIdx >= 0 && + (TopX(*prevE, pt.Y) == TopX(*e, pt.Y)) && + SlopesEqual(*e, *prevE, m_UseFullRange)) + AddJoin(e, prevE, -1, -1); } //------------------------------------------------------------------------------ void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt) { - AddOutPt( e1, 0, pt ); + AddOutPt( e1, pt ); if( e1->outIdx == e2->outIdx ) { e1->outIdx = -1; e2->outIdx = -1; } - else - AppendPolygon( e1, e2 ); + else if (e1->outIdx < e2->outIdx) + AppendPolygon(e1, e2); + else + AppendPolygon(e2, e1); } //------------------------------------------------------------------------------ @@ -1620,12 +1703,6 @@ void Clipper::InsertLocalMinimaIntoAEL( const long64 botY) if( IsContributing(*lb) ) AddLocalMinPoly( lb, rb, IntPoint(lb->xcurr, m_CurrentLM->Y) ); - //if output polygons share an edge, they'll need joining later ... - if (lb->outIdx >= 0 && lb->prevInAEL && - lb->prevInAEL->outIdx >= 0 && lb->prevInAEL->xcurr == lb->xbot && - SlopesEqual(*lb, *lb->prevInAEL, m_UseFullRange)) - AddJoin(lb, lb->prevInAEL); - //if any output polygons share an edge, they'll need joining later ... if (rb->outIdx >= 0) { @@ -1818,10 +1895,8 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, AddLocalMinPoly(e1, e2, pt); break; case ctDifference: - if ((e1->polyType == ptClip && e2->polyType == ptClip && - e1Wc2 > 0 && e2Wc2 > 0) || - (e1->polyType == ptSubject && e2->polyType == ptSubject && - e1Wc2 <= 0 && e2Wc2 <= 0)) + if (((e1->polyType == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) || + ((e1->polyType == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0))) AddLocalMinPoly(e1, e2, pt); break; case ctXor: @@ -1862,24 +1937,6 @@ void Clipper::SetHoleState(TEdge *e, OutRec *outRec) } //------------------------------------------------------------------------------ -bool GetNextNonDupOutPt(OutPt* pp, OutPt*& next) -{ - next = pp->next; - while (next != pp && PointsEqual(pp->pt, next->pt)) - next = next->next; - return next != pp; -} -//------------------------------------------------------------------------------ - -bool GetPrevNonDupOutPt(OutPt* pp, OutPt*& prev) -{ - prev = pp->prev; - while (prev != pp && PointsEqual(pp->pt, prev->pt)) - prev = prev->prev; - return prev != pp; -} -//------------------------------------------------------------------------------ - OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) { //work out which polygon fragment has the correct hole state ... @@ -1889,21 +1946,21 @@ OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2) else if (outPt1->pt.Y < outPt2->pt.Y) return outRec2; else if (outPt1->pt.X < outPt2->pt.X) return outRec1; else if (outPt1->pt.X > outPt2->pt.X) return outRec2; - else if (outRec1->bottomE2 == 0) return outRec2; - else if (outRec2->bottomE2 == 0) return outRec1; - else + else if (outPt1->next == outPt1) return outRec2; + else if (outPt2->next == outPt2) return outRec1; + else if (FirstIsBottomPt(outPt1, outPt2)) return outRec1; + else return outRec2; +} +//------------------------------------------------------------------------------ + +bool Param1RightOfParam2(OutRec* outRec1, OutRec* outRec2) +{ + do { - long64 y1 = std::max(outRec1->bottomE1->ybot, outRec1->bottomE2->ybot); - long64 y2 = std::max(outRec2->bottomE1->ybot, outRec2->bottomE2->ybot); - if (y2 == y1 || (y1 > outPt1->pt.Y && y2 > outPt1->pt.Y)) - { - double dx1 = std::max(outRec1->bottomE1->dx, outRec1->bottomE2->dx); - double dx2 = std::max(outRec2->bottomE1->dx, outRec2->bottomE2->dx); - if (dx2 > dx1) return outRec2; else return outRec1; - } - else if (y2 > y1) return outRec2; - else return outRec1; - } + outRec1 = outRec1->FirstLeft; + if (outRec1 == outRec2) return true; + } while (outRec1); + return false; } //------------------------------------------------------------------------------ @@ -1912,13 +1969,11 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) //get the start and ends of both output polygons ... OutRec *outRec1 = m_PolyOuts[e1->outIdx]; OutRec *outRec2 = m_PolyOuts[e2->outIdx]; - OutRec *holeStateRec = GetLowermostRec(outRec1, outRec2); - //fixup hole status ... - if (holeStateRec == outRec2) - outRec1->isHole = outRec2->isHole; - else - outRec2->isHole = outRec1->isHole; + OutRec *holeStateRec; + if (Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2; + else if (Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1; + else holeStateRec = GetLowermostRec(outRec1, outRec2); OutPt* p1_lft = outRec1->pts; OutPt* p1_rt = p1_lft->prev; @@ -1973,11 +2028,9 @@ void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) { outRec1->bottomPt = outRec2->bottomPt; outRec1->bottomPt->idx = outRec1->idx; - outRec1->bottomE1 = outRec2->bottomE1; - outRec1->bottomE2 = outRec2->bottomE2; - if (outRec2->FirstLeft != outRec1) outRec1->FirstLeft = outRec2->FirstLeft; + outRec1->isHole = outRec2->isHole; } outRec2->pts = 0; outRec2->bottomPt = 0; @@ -2023,11 +2076,27 @@ OutRec* Clipper::CreateOutRec() result->AppendLink = 0; result->pts = 0; result->bottomPt = 0; + result->sides = esNeither; + result->bottomFlag = 0; + return result; } //------------------------------------------------------------------------------ -void Clipper::AddOutPt(TEdge *e, TEdge *altE, const IntPoint &pt) +void Clipper::DisposeBottomPt(OutRec &outRec) +{ + OutPt* next = outRec.bottomPt->next; + OutPt* prev = outRec.bottomPt->prev; + if (outRec.pts == outRec.bottomPt) outRec.pts = next; + delete outRec.bottomPt; + next->prev = prev; + prev->next = next; + outRec.bottomPt = next; + FixupOutPolygon(outRec); +} +//------------------------------------------------------------------------------ + +void Clipper::AddOutPt(TEdge *e, const IntPoint &pt) { bool ToFront = (e->side == esLeft); if( e->outIdx < 0 ) @@ -2038,8 +2107,6 @@ void Clipper::AddOutPt(TEdge *e, TEdge *altE, const IntPoint &pt) e->outIdx = outRec->idx; OutPt* op = new OutPt; outRec->pts = op; - outRec->bottomE1 = e; - outRec->bottomE2 = altE; outRec->bottomPt = op; op->pt = pt; op->idx = outRec->idx; @@ -2052,16 +2119,59 @@ void Clipper::AddOutPt(TEdge *e, TEdge *altE, const IntPoint &pt) OutPt* op = outRec->pts; if ((ToFront && PointsEqual(pt, op->pt)) || (!ToFront && PointsEqual(pt, op->prev->pt))) return; + + if ((e->side | outRec->sides) != outRec->sides) + { + //check for 'rounding' artefacts ... + if (outRec->sides == esNeither && pt.Y == op->pt.Y) + if (ToFront) + { + if (pt.X == op->pt.X +1) return; //ie wrong side of bottomPt + } + else if (pt.X == op->pt.X -1) return; //ie wrong side of bottomPt + + outRec->sides = (EdgeSide)(outRec->sides | e->side); + if (outRec->sides == esBoth) + { + //A vertex from each side has now been added. + //Vertices of one side of an output polygon are quite commonly close to + //or even 'touching' edges of the other side of the output polygon. + //Very occasionally vertices from one side can 'cross' an edge on the + //the other side. The distance 'crossed' is always less that a unit + //and is purely an artefact of coordinate rounding. Nevertheless, this + //results in very tiny self-intersections. Because of the way + //orientation is calculated, even tiny self-intersections can cause + //the Orientation function to return the wrong result. Therefore, it's + //important to ensure that any self-intersections close to BottomPt are + //detected and removed before orientation is assigned. + + OutPt *opBot, *op2; + if (ToFront) + { + opBot = outRec->pts; + op2 = opBot->next; //op2 == right side + if (opBot->pt.Y != op2->pt.Y && opBot->pt.Y != pt.Y && + ((opBot->pt.X - pt.X)/(opBot->pt.Y - pt.Y) < + (opBot->pt.X - op2->pt.X)/(opBot->pt.Y - op2->pt.Y))) + outRec->bottomFlag = opBot; + } else + { + opBot = outRec->pts->prev; + op2 = opBot->prev; //op2 == left side + if (opBot->pt.Y != op2->pt.Y && opBot->pt.Y != pt.Y && + ((opBot->pt.X - pt.X)/(opBot->pt.Y - pt.Y) > + (opBot->pt.X - op2->pt.X)/(opBot->pt.Y - op2->pt.Y))) + outRec->bottomFlag = opBot; + } + } + } + OutPt* op2 = new OutPt; op2->pt = pt; op2->idx = outRec->idx; if (op2->pt.Y == outRec->bottomPt->pt.Y && op2->pt.X < outRec->bottomPt->pt.X) - { - outRec->bottomPt = op2; - outRec->bottomE1 = e; - outRec->bottomE2 = altE; - } + outRec->bottomPt = op2; op2->next = op; op2->prev = op->prev; op2->prev->next = op2; @@ -2216,8 +2326,7 @@ void Clipper::SwapPositionsInSEL(TEdge *edge1, TEdge *edge2) TEdge* GetNextInAEL(TEdge *e, Direction dir) { - if( dir == dLeftToRight ) return e->nextInAEL; - else return e->prevInAEL; + return dir == dLeftToRight ? e->nextInAEL : e->prevInAEL; } //------------------------------------------------------------------------------ @@ -2310,7 +2419,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge) if( horzEdge->nextInLML ) { if( horzEdge->outIdx >= 0 ) - AddOutPt( horzEdge, 0, IntPoint(horzEdge->xtop, horzEdge->ytop)); + AddOutPt( horzEdge, IntPoint(horzEdge->xtop, horzEdge->ytop)); UpdateEdgeIntoAEL( horzEdge ); } else @@ -2426,7 +2535,7 @@ void Clipper::BuildIntersectList(const long64 botY, const long64 topY) } //------------------------------------------------------------------------------ -bool Process1Before2(IntersectNode &node1, IntersectNode &node2) +bool ProcessParam1BeforeParam2(IntersectNode &node1, IntersectNode &node2) { bool result; if (node1.pt.Y == node2.pt.Y) @@ -2434,12 +2543,12 @@ bool Process1Before2(IntersectNode &node1, IntersectNode &node2) if (node1.edge1 == node2.edge1 || node1.edge2 == node2.edge1) { result = node2.pt.X > node1.pt.X; - if (node2.edge1->dx > 0) return !result; else return result; + return node2.edge1->dx > 0 ? !result : result; } else if (node1.edge1 == node2.edge2 || node1.edge2 == node2.edge2) { result = node2.pt.X > node1.pt.X; - if (node2.edge2->dx > 0) return !result; else return result; + return node2.edge2->dx > 0 ? !result : result; } else return node2.pt.X > node1.pt.X; } @@ -2455,7 +2564,7 @@ void Clipper::AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt) newNode->pt = pt; newNode->next = 0; if( !m_IntersectNodes ) m_IntersectNodes = newNode; - else if( Process1Before2(*newNode, *m_IntersectNodes) ) + else if( ProcessParam1BeforeParam2(*newNode, *m_IntersectNodes) ) { newNode->next = m_IntersectNodes; m_IntersectNodes = newNode; @@ -2463,7 +2572,7 @@ void Clipper::AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt) else { IntersectNode* iNode = m_IntersectNodes; - while( iNode->next && Process1Before2(*iNode->next, *newNode) ) + while( iNode->next && ProcessParam1BeforeParam2(*iNode->next, *newNode) ) iNode = iNode->next; newNode->next = iNode->next; iNode->next = newNode; @@ -2533,7 +2642,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const long64 topY) { if (e->outIdx >= 0) { - AddOutPt(e, 0, IntPoint(e->xtop, e->ytop)); + AddOutPt(e, IntPoint(e->xtop, e->ytop)); for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i) { @@ -2569,7 +2678,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const long64 topY) { if( IsIntermediate( e, topY ) ) { - if( e->outIdx >= 0 ) AddOutPt(e, 0, IntPoint(e->xtop,e->ytop)); + if( e->outIdx >= 0 ) AddOutPt(e, IntPoint(e->xtop,e->ytop)); UpdateEdgeIntoAEL(e); //if output polygons share an edge, they'll need joining later ... @@ -2579,18 +2688,18 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const long64 topY) IntPoint(e->xbot,e->ybot), IntPoint(e->prevInAEL->xtop, e->prevInAEL->ytop), m_UseFullRange)) { - AddOutPt(e->prevInAEL, 0, IntPoint(e->xbot, e->ybot)); + AddOutPt(e->prevInAEL, IntPoint(e->xbot, e->ybot)); AddJoin(e, e->prevInAEL); } else if (e->outIdx >= 0 && e->nextInAEL && e->nextInAEL->outIdx >= 0 && e->nextInAEL->ycurr > e->nextInAEL->ytop && - e->nextInAEL->ycurr < e->nextInAEL->ybot && + e->nextInAEL->ycurr <= e->nextInAEL->ybot && e->nextInAEL->xcurr == e->xbot && e->nextInAEL->ycurr == e->ybot && SlopesEqual(IntPoint(e->xbot,e->ybot), IntPoint(e->xtop, e->ytop), IntPoint(e->xbot,e->ybot), IntPoint(e->nextInAEL->xtop, e->nextInAEL->ytop), m_UseFullRange)) { - AddOutPt(e->nextInAEL, 0, IntPoint(e->xbot, e->ybot)); + AddOutPt(e->nextInAEL, IntPoint(e->xbot, e->ybot)); AddJoin(e, e->nextInAEL); } } @@ -2623,13 +2732,7 @@ void Clipper::FixupOutPolygon(OutRec &outRec) lastOK = 0; OutPt *tmp = pp; if (pp == outRec.bottomPt) - { - if (tmp->prev->pt.Y > tmp->next->pt.Y) - outRec.bottomPt = tmp->prev; else - outRec.bottomPt = tmp->next; - outRec.pts = outRec.bottomPt; - outRec.bottomPt->idx = outRec.idx; - } + outRec.bottomPt = 0; //flags need for updating pp->prev->next = pp->next; pp->next->prev = pp->prev; pp = pp->prev; @@ -2642,6 +2745,11 @@ void Clipper::FixupOutPolygon(OutRec &outRec) pp = pp->next; } } + if (!outRec.bottomPt) { + outRec.bottomPt = GetBottomPt(pp); + outRec.bottomPt->idx = outRec.idx; + outRec.pts = outRec.bottomPt; + } } //------------------------------------------------------------------------------ @@ -2766,8 +2874,7 @@ bool Clipper::FixupIntersections() bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2) { - if (e2.xcurr == e1.xcurr) return e2.dx > e1.dx; - else return e2.xcurr < e1.xcurr; + return e2.xcurr == e1.xcurr ? e2.dx > e1.dx : e2.xcurr < e1.xcurr; } //------------------------------------------------------------------------------ @@ -2799,7 +2906,7 @@ void Clipper::InsertEdgeIntoAEL(TEdge *edge) void Clipper::DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt) { - AddOutPt(edge1, edge2, pt); + AddOutPt(edge1, pt); SwapSides(*edge1, *edge2); SwapPolyIndexes(*edge1, *edge2); } @@ -2807,7 +2914,7 @@ void Clipper::DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt) void Clipper::DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt) { - AddOutPt(edge2, edge1, pt); + AddOutPt(edge2, pt); SwapSides(*edge1, *edge2); SwapPolyIndexes(*edge1, *edge2); } @@ -2815,8 +2922,8 @@ void Clipper::DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt) void Clipper::DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt) { - AddOutPt(edge1, edge2, pt); - AddOutPt(edge2, edge1, pt); + AddOutPt(edge1, pt); + AddOutPt(edge2, pt); SwapSides( *edge1 , *edge2 ); SwapPolyIndexes( *edge1 , *edge2 ); } @@ -2920,31 +3027,37 @@ void Clipper::JoinCommonEdges(bool fixHoleLinkages) { //instead of joining two polygons, we've just created a new one by //splitting one polygon into two. - outRec1->pts = PolygonBottom(p1); + outRec1->pts = GetBottomPt(p1); outRec1->bottomPt = outRec1->pts; outRec1->bottomPt->idx = outRec1->idx; outRec2 = CreateOutRec(); m_PolyOuts.push_back(outRec2); outRec2->idx = (int)m_PolyOuts.size()-1; j->poly2Idx = outRec2->idx; - outRec2->pts = PolygonBottom(p2); + outRec2->pts = GetBottomPt(p2); outRec2->bottomPt = outRec2->pts; outRec2->bottomPt->idx = outRec2->idx; if (PointInPolygon(outRec2->pts->pt, outRec1->pts, m_UseFullRange)) { + //outRec2 is contained by outRec1 ... outRec2->isHole = !outRec1->isHole; outRec2->FirstLeft = outRec1; - if (outRec2->isHole == Orientation(outRec2, m_UseFullRange)) - ReversePolyPtLinks(*outRec2->pts); + if (outRec2->isHole == + (m_ReverseOutput ^ Orientation(outRec2, m_UseFullRange))) + ReversePolyPtLinks(*outRec2->pts); } else if (PointInPolygon(outRec1->pts->pt, outRec2->pts, m_UseFullRange)) { + //outRec1 is contained by outRec2 ... outRec2->isHole = outRec1->isHole; outRec1->isHole = !outRec2->isHole; outRec2->FirstLeft = outRec1->FirstLeft; outRec1->FirstLeft = outRec2; - if (outRec1->isHole == Orientation(outRec1, m_UseFullRange)) - ReversePolyPtLinks(*outRec1->pts); + if (outRec1->isHole == + (m_ReverseOutput ^ Orientation(outRec1, m_UseFullRange))) + ReversePolyPtLinks(*outRec1->pts); + //make sure any contained holes now link to the correct polygon ... + if (fixHoleLinkages) CheckHoleLinkages1(outRec1, outRec2); } else { outRec2->isHole = outRec1->isHole; @@ -2966,6 +3079,12 @@ void Clipper::JoinCommonEdges(bool fixHoleLinkages) //now cleanup redundant edges too ... FixupOutPolygon(*outRec1); FixupOutPolygon(*outRec2); + + if (Orientation(outRec1, m_UseFullRange) != (Area(*outRec1, m_UseFullRange) > 0)) + DisposeBottomPt(*outRec1); + if (Orientation(outRec2, m_UseFullRange) != (Area(*outRec2, m_UseFullRange) > 0)) + DisposeBottomPt(*outRec2); + } else { //joined 2 polygons together ... @@ -2973,14 +3092,22 @@ void Clipper::JoinCommonEdges(bool fixHoleLinkages) //make sure any holes contained by outRec2 now link to outRec1 ... if (fixHoleLinkages) CheckHoleLinkages2(outRec1, outRec2); + //now cleanup redundant edges too ... + FixupOutPolygon(*outRec1); + + if (outRec1->pts) + { + outRec1->isHole = !Orientation(outRec1, m_UseFullRange); + if (outRec1->isHole && !outRec1->FirstLeft) + outRec1->FirstLeft = outRec2->FirstLeft; + } + //delete the obsolete pointer ... int OKIdx = outRec1->idx; int ObsoleteIdx = outRec2->idx; outRec2->pts = 0; outRec2->bottomPt = 0; outRec2->AppendLink = outRec1; - //holes are practically always joined to outers, not vice versa ... - if (outRec1->isHole && !outRec2->isHole) outRec1->isHole = false; //now fixup any subsequent Joins that match this polygon for (JoinList::size_type k = i+1; k < m_Joins.size(); k++) @@ -2989,27 +3116,21 @@ void Clipper::JoinCommonEdges(bool fixHoleLinkages) if (j2->poly1Idx == ObsoleteIdx) j2->poly1Idx = OKIdx; if (j2->poly2Idx == ObsoleteIdx) j2->poly2Idx = OKIdx; } - - //now cleanup redundant edges too ... - if (outRec1->pts) - FixupOutPolygon(*outRec1); - else - FixupOutPolygon(*outRec2); } } } //------------------------------------------------------------------------------ -void ReversePoints(Polygon& p) +void ReversePolygon(Polygon& p) { std::reverse(p.begin(), p.end()); } //------------------------------------------------------------------------------ -void ReversePoints(Polygons& p) +void ReversePolygons(Polygons& p) { for (Polygons::size_type i = 0; i < p.size(); ++i) - ReversePoints(p[i]); + ReversePolygon(p[i]); } //------------------------------------------------------------------------------ @@ -3027,12 +3148,13 @@ struct DoublePoint Polygon BuildArc(const IntPoint &pt, const double a1, const double a2, const double r) { - int steps = std::max(6, int(std::sqrt(std::fabs(r)) * std::fabs(a2 - a1))); - Polygon result(steps); - int n = steps - 1; - double da = (a2 - a1) / n; + long64 steps = std::max(6, int(std::sqrt(std::fabs(r)) * std::fabs(a2 - a1))); + if (steps > 0x100000) steps = 0x100000; + int n = (unsigned)steps; + Polygon result(n); + double da = (a2 - a1) / (n -1); double a = a1; - for (int i = 0; i <= n; ++i) + for (int i = 0; i < n; ++i) { result[i].X = pt.X + Round(std::cos(a)*r); result[i].Y = pt.Y + Round(std::sin(a)*r); @@ -3160,7 +3282,7 @@ PolyOffsetBuilder(const Polygons& in_polys, Polygons& out_polys, if (clpr.Execute(ctUnion, out_polys, pftNegative, pftNegative)) { out_polys.erase(out_polys.begin()); - ReversePoints(out_polys); + ReversePolygons(out_polys); } else out_polys.clear(); @@ -3187,23 +3309,23 @@ void DoSquare(double mul = 1.0) (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta)); if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0) { - double a1 = std::atan2(normals[m_k].Y, normals[m_k].X); - double a2 = std::atan2(-normals[m_j].Y, -normals[m_j].X); - a1 = std::fabs(a2 - a1); - if (a1 > pi) a1 = pi * 2 - a1; - double dx = std::tan((pi - a1)/4) * std::fabs(m_delta * mul); - pt1 = IntPoint((long64)(pt1.X -normals[m_k].Y * dx), - (long64)(pt1.Y + normals[m_k].X * dx)); - AddPoint(pt1); - pt2 = IntPoint((long64)(pt2.X + normals[m_j].Y * dx), - (long64)(pt2.Y -normals[m_j].X * dx)); - AddPoint(pt2); + double a1 = std::atan2(normals[m_k].Y, normals[m_k].X); + double a2 = std::atan2(-normals[m_j].Y, -normals[m_j].X); + a1 = std::fabs(a2 - a1); + if (a1 > pi) a1 = pi * 2 - a1; + double dx = std::tan((pi - a1)/4) * std::fabs(m_delta * mul); + pt1 = IntPoint((long64)(pt1.X -normals[m_k].Y * dx), + (long64)(pt1.Y + normals[m_k].X * dx)); + AddPoint(pt1); + pt2 = IntPoint((long64)(pt2.X + normals[m_j].Y * dx), + (long64)(pt2.Y -normals[m_j].X * dx)); + AddPoint(pt2); } else { - AddPoint(pt1); - AddPoint(m_p[m_i][m_j]); - AddPoint(pt2); + AddPoint(pt1); + AddPoint(m_p[m_i][m_j]); + AddPoint(pt2); } } //------------------------------------------------------------------------------ @@ -3274,6 +3396,28 @@ void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, } //------------------------------------------------------------------------------ +void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType) +{ + Clipper c; + c.AddPolygon(in_poly, ptSubject); + c.Execute(ctUnion, out_polys, fillType, fillType); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType) +{ + Clipper c; + c.AddPolygons(in_polys, ptSubject); + c.Execute(ctUnion, out_polys, fillType, fillType); +} +//------------------------------------------------------------------------------ + +void SimplifyPolygons(Polygons &polys, PolyFillType fillType) +{ + SimplifyPolygons(polys, polys, fillType); +} +//------------------------------------------------------------------------------ + std::ostream& operator <<(std::ostream &s, IntPoint& p) { s << p.X << ' ' << p.Y << "\n"; diff --git a/src/3rdparty/assimp/contrib/clipper/clipper.hpp b/src/3rdparty/assimp/contrib/clipper/clipper.hpp index 57d81136c..f6f196d0d 100644 --- a/src/3rdparty/assimp/contrib/clipper/clipper.hpp +++ b/src/3rdparty/assimp/contrib/clipper/clipper.hpp @@ -1,10 +1,10 @@ /******************************************************************************* * * * Author : Angus Johnson * -* Version : 4.6.3 * -* Date : 11 November 2011 * +* Version : 4.8.8 * +* Date : 30 August 2012 * * Website : http://www.angusj.com * -* Copyright : Angus Johnson 2010-2011 * +* Copyright : Angus Johnson 2010-2012 * * * * License: * * Use, modification & distribution is subject to Boost Software License Ver 1. * @@ -73,18 +73,21 @@ struct ExPolygon { }; typedef std::vector< ExPolygon > ExPolygons; -enum JoinType { jtSquare, jtMiter, jtRound }; +enum JoinType { jtSquare, jtRound, jtMiter }; bool Orientation(const Polygon &poly); double Area(const Polygon &poly); void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys, double delta, JoinType jointype = jtSquare, double MiterLimit = 2); +void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd); +void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd); +void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd); -void ReversePoints(Polygon& p); -void ReversePoints(Polygons& p); +void ReversePolygon(Polygon& p); +void ReversePolygons(Polygons& p); //used internally ... -enum EdgeSide { esLeft, esRight }; +enum EdgeSide { esNeither = 0, esLeft = 1, esRight = 2, esBoth = 3 }; enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 }; struct TEdge { @@ -139,8 +142,8 @@ struct OutRec { OutRec *AppendLink; OutPt *pts; OutPt *bottomPt; - TEdge *bottomE1; - TEdge *bottomE2; + OutPt *bottomFlag; + EdgeSide sides; }; struct OutPt { @@ -256,9 +259,10 @@ private: void IntersectEdges(TEdge *e1, TEdge *e2, const IntPoint &pt, IntersectProtects protects); OutRec* CreateOutRec(); - void AddOutPt(TEdge *e, TEdge *altE, const IntPoint &pt); + void AddOutPt(TEdge *e, const IntPoint &pt); + void DisposeBottomPt(OutRec &outRec); void DisposeAllPolyPts(); - void DisposeOutRec(PolyOutList::size_type index, bool ignorePts = false); + void DisposeOutRec(PolyOutList::size_type index); bool ProcessIntersections(const long64 botY, const long64 topY); void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt); void BuildIntersectList(const long64 botY, const long64 topY); diff --git a/src/3rdparty/assimp/contrib/cppunit_note.txt b/src/3rdparty/assimp/contrib/cppunit_note.txt deleted file mode 100644 index 15e8db713..000000000 --- a/src/3rdparty/assimp/contrib/cppunit_note.txt +++ /dev/null @@ -1,8 +0,0 @@ -This is a "slim" version of CPPunit. It contains everything we need, but nothing more. - -- Tools have been removed -- x64-Build configs have been added -- VC6 build & headers have been removed (Assimp can't be compiled with vc6) -- vc9 solution has been added, vc8 solution uses Assimp 'FastSTL' settings - ---- Alex
\ No newline at end of file diff --git a/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h b/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h index bf5f55de5..63b700dc1 100644 --- a/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h +++ b/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h @@ -215,7 +215,7 @@ private: { char_type* start = P; - // more forward until '<' found + // move forward until '<' found while(*P != L'<' && *P) ++P; diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.cc b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.cc index be0f05f2e..4080445a7 100644 --- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.cc +++ b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.cc @@ -119,10 +119,10 @@ void Triangle::ClearDelunayEdges() Point* Triangle::OppositePoint(Triangle& t, Point& p) { Point *cw = t.PointCW(p); -// double x = cw->x; -// double y = cw->y; -// x = p.x; -// y = p.y; + //double x = cw->x; + //double y = cw->y; + //x = p.x; + //y = p.y; return PointCW(*cw); } @@ -164,7 +164,8 @@ int Triangle::Index(const Point* p) return 2; } assert(0); - return -1; // fix compiler warning + + return 0; } int Triangle::EdgeIndex(const Point* p1, const Point* p2) @@ -224,7 +225,8 @@ Point* Triangle::PointCW(Point& point) return points_[1]; } assert(0); - return NULL; // fix compiler warning + + return 0; } // The point counter-clockwise to given point @@ -238,7 +240,8 @@ Point* Triangle::PointCCW(Point& point) return points_[0]; } assert(0); - return NULL; + + return 0; } // The neighbor clockwise to given point diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.h index d63f6a5be..4f691838f 100644 --- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.h +++ b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.h @@ -38,6 +38,7 @@ #include <stdexcept> #include <assert.h> #include <cmath> +#include <string> namespace p2t { @@ -137,8 +138,8 @@ struct Edge { p = &p2; } else if (p1.x == p2.x) { // Repeat points - // ASSIMP_CHANGE (aramis_acg) - throw std::runtime_error("repeat points"); + // ASSIMP_CHANGE (aramis_acg) + throw std::runtime_error(std::string("repeat points")); //assert(false); } } diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.cc b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.cc index c67a9773a..e02226bd1 100644 --- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.cc +++ b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.cc @@ -754,7 +754,7 @@ void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& Sweep::~Sweep() { // Clean up memory - for(int i = 0; i < static_cast<int>(nodes_.size()); i++) { + for(unsigned int i = 0; i < nodes_.size(); i++) { delete nodes_[i]; } diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.cc b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.cc index fbe04b89a..c9dd5a8c4 100644 --- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.cc +++ b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.cc @@ -96,7 +96,7 @@ void SweepContext::InitTriangulation() void SweepContext::InitEdges(std::vector<Point*> polyline) { - int num_points = static_cast<int>( polyline.size() ); + int num_points = polyline.size(); for (int i = 0; i < num_points; i++) { int j = i < num_points - 1 ? i + 1 : 0; edge_list.push_back(new Edge(*polyline[i], *polyline[j])); diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.h index 2f7d8e982..1010c0e8a 100644 --- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.h +++ b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.h @@ -158,7 +158,7 @@ inline AdvancingFront* SweepContext::front() inline int SweepContext::point_count() { - return static_cast<int>(points_.size()); + return points_.size(); } inline void SweepContext::set_head(Point* p1) diff --git a/src/3rdparty/assimp/contrib/unzip/unzip.h b/src/3rdparty/assimp/contrib/unzip/unzip.h index e3b7f24ee..600dfaa41 100644 --- a/src/3rdparty/assimp/contrib/unzip/unzip.h +++ b/src/3rdparty/assimp/contrib/unzip/unzip.h @@ -45,9 +45,6 @@ #ifndef _unz_H #define _unz_H -#ifdef __cplusplus -extern "C" { -#endif #ifndef _ZLIB_H # ifdef ASSIMP_BUILD_NO_OWN_ZLIB @@ -57,6 +54,17 @@ extern "C" { # endif #endif +// This needs to be moved down a bit otherwise +// when using the Zlib headers bundled with Qt +// an extern C block is redefined within another +// extern C block resulting in an extern C dangling +// around causing hundred of template with C linkage e +// errors + +#ifdef __cplusplus +extern "C" { +#endif + #ifndef _ZLIBIOAPI_H #include "ioapi.h" #endif diff --git a/src/3rdparty/assimp/contrib/zlib/CMakeLists.txt b/src/3rdparty/assimp/contrib/zlib/CMakeLists.txt deleted file mode 100644 index 7057628e7..000000000 --- a/src/3rdparty/assimp/contrib/zlib/CMakeLists.txt +++ /dev/null @@ -1,141 +0,0 @@ -check_include_file(sys/types.h HAVE_SYS_TYPES_H) -check_include_file(stdint.h HAVE_STDINT_H) -check_include_file(stddef.h HAVE_STDDEF_H) - -# -# Check to see if we have large file support -# -set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) -# We add these other definitions here because CheckTypeSize.cmake -# in CMake 2.4.x does not automatically do so and we want -# compatibility with CMake 2.4.x. -if(HAVE_SYS_TYPES_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) -endif() -if(HAVE_STDINT_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) -endif() -if(HAVE_STDDEF_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) -endif() - -check_type_size(off64_t OFF64_T) -if(HAVE_OFF64_T) - add_definitions(-D_LARGEFILE64_SOURCE=1) -endif() -set(CMAKE_REQUIRED_DEFINITIONS) # clear variable - -# -# Check for fseeko -# -check_function_exists(fseeko HAVE_FSEEKO) -if(NOT HAVE_FSEEKO) - add_definitions(-DNO_FSEEKO) -endif() - -# -# Check for unistd.h -# -check_include_file(unistd.h Z_HAVE_UNISTD_H) - -if(MSVC) - set(CMAKE_DEBUG_POSTFIX "d") - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) -endif() - -if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - # If we're doing an out of source build and the user has a zconf.h - # in their source tree... - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) - message(FATAL_ERROR - "You must remove ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h " - "from the source tree. This file is included with zlib " - "but CMake generates this file for you automatically " - "in the build directory.") - endif() -endif() - -#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zconf.in.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h @ONLY) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - - -#============================================================================ -# zlib -#============================================================================ - -set(ZLIB_PUBLIC_HDRS - ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h - zlib.h -) -set(ZLIB_PRIVATE_HDRS -crc32.h deflate.h inffast.h inffixed.h inflate.h inftrees.h trees.h zconf.h zlib.h zutil.h - -) -set(ZLIB_SRCS - adler32.c compress.c crc32.c deflate.c inffast.c inflate.c inftrees.c trees.c zutil.c -) - -# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) -string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9A-Za-z.]+)\".*" - "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) - -add_library(zlib STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS}") - -set_target_properties(zlib PROPERTIES SOVERSION 1) - -if(NOT CYGWIN) - # This property causes shared libraries on Linux to have the full version - # encoded into their final filename. We disable this on Cygwin because - # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll - # seems to be the default. - # - # This has no effect with MSVC, on that platform the version info for - # the DLL comes from the resource file win32/zlib1.rc - set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) -endif() - -if(UNIX) - # On unix-like platforms the library is almost always called libz - set_target_properties(zlib PROPERTIES OUTPUT_NAME z) -elseif(BUILD_SHARED_LIBS AND WIN32) - # Creates zlib1.dll when building shared library version - set_target_properties(zlib PROPERTIES SUFFIX "1.dll") -endif() - -#if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) -# install(TARGETS zlib -# RUNTIME DESTINATION bin -# ARCHIVE DESTINATION lib -# LIBRARY DESTINATION lib ) -#endif() -#if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) -# install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION include) -#endif() -#if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) -# install(FILES zlib.3 DESTINATION share/man/man3) -#endif() - -#============================================================================ -# Example binaries -#============================================================================ - -#add_executable(example example.c) -#target_link_libraries(example zlib) -#add_test(example example) -# -#add_executable(minigzip minigzip.c) -#target_link_libraries(minigzip zlib) -# -#if(HAVE_OFF64_T) -# add_executable(example64 example.c) -# target_link_libraries(example64 zlib) -# set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") -# add_test(example64 example64) -# -# add_executable(minigzip64 minigzip.c) -# target_link_libraries(minigzip64 zlib) -# set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") -#endif() diff --git a/src/3rdparty/assimp/contrib/zlib/README b/src/3rdparty/assimp/contrib/zlib/README deleted file mode 100644 index d4219bf88..000000000 --- a/src/3rdparty/assimp/contrib/zlib/README +++ /dev/null @@ -1,115 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.5 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file example.c which also tests that the library -is working correctly. Another example is given in the file minigzip.c. The -compression library itself is composed of all source files except example.c and -minigzip.c. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile.in. In short "./configure; make test", and if that goes -well, "make install" should work for most flavors of Unix. For Windows, use one -of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use -make_vms.com. - -Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant -<info@winimage.com> for the Windows DLL version. The zlib home page is -http://zlib.net/ . Before reporting a problem, please check this site to -verify that you have the latest version of zlib; otherwise get the latest -version and check whether the problem still exists or not. - -PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. - -Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available at -http://marknelson.us/1997/01/01/zlib-engine/ . - -The changes made in version 1.2.5 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory contrib/ . - -zlib is available in Java using the java.util.zip package, documented at -http://java.sun.com/developer/technicalArticles/Programming/compression/ . - -A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available -at CPAN (Comprehensive Perl Archive Network) sites, including -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . - -A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is -available in Python 1.5 and later versions, see -http://www.python.org/doc/lib/module-zlib.html . - -zlib is built into tcl: http://wiki.tcl.tk/4610 . - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant <info@winimage.com>, is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS or BEOS. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate and - zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; they - are too numerous to cite here. - -Copyright notice: - - (C) 1995-2010 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. diff --git a/src/3rdparty/assimp/contrib/zlib/adler32.c b/src/3rdparty/assimp/contrib/zlib/adler32.c deleted file mode 100644 index 65ad6a5ad..000000000 --- a/src/3rdparty/assimp/contrib/zlib/adler32.c +++ /dev/null @@ -1,169 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2007 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#define local static - -local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); - -#define BASE 65521UL /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware */ -#ifdef NO_DIVIDE -# define MOD(a) \ - do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD4(a) \ - do { \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD4(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD4(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* the derivation of this formula is left as an exercise for the reader */ - rem = (unsigned)(len2 % BASE); - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/src/3rdparty/assimp/contrib/zlib/compress.c b/src/3rdparty/assimp/contrib/zlib/compress.c deleted file mode 100644 index ea4dfbe9d..000000000 --- a/src/3rdparty/assimp/contrib/zlib/compress.c +++ /dev/null @@ -1,80 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/src/3rdparty/assimp/contrib/zlib/crc32.c b/src/3rdparty/assimp/contrib/zlib/crc32.c deleted file mode 100644 index 91be372d2..000000000 --- a/src/3rdparty/assimp/contrib/zlib/crc32.c +++ /dev/null @@ -1,442 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - */ - -#ifdef MAKECRCH -# include <stdio.h> -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# include <limits.h> -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - -/* Definitions for doing the crc four data bytes at a time. */ -#ifdef BYFOUR -# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); - - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local unsigned long FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - unsigned long c; - int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (unsigned long)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const unsigned long FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const unsigned long FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const unsigned long FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = (u4)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = REV((u4)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(REV(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} - -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} diff --git a/src/3rdparty/assimp/contrib/zlib/crc32.h b/src/3rdparty/assimp/contrib/zlib/crc32.h deleted file mode 100644 index 8053b6117..000000000 --- a/src/3rdparty/assimp/contrib/zlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const unsigned long FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/src/3rdparty/assimp/contrib/zlib/deflate.c b/src/3rdparty/assimp/contrib/zlib/deflate.c deleted file mode 100644 index 5c4022f3d..000000000 --- a/src/3rdparty/assimp/contrib/zlib/deflate.c +++ /dev/null @@ -1,1834 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) - return Z_STREAM_ERROR; - - s = strm->state; - if (s->wrap) - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > s->w_size) { - length = s->w_size; - dictionary += dictLength - length; /* use the tail of the dictionary */ - } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - Bytef *str; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len = strm->state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, strm->state->pending_out, len); - strm->next_out += len; - strm->state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush)); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy(dest, source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); - } -#endif - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest encodable run. - */ - if (s->lookahead < MAX_MATCH) { - fill_window(s); - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} diff --git a/src/3rdparty/assimp/contrib/zlib/deflate.h b/src/3rdparty/assimp/contrib/zlib/deflate.h deleted file mode 100644 index cbf0d1ea5..000000000 --- a/src/3rdparty/assimp/contrib/zlib/deflate.h +++ /dev/null @@ -1,342 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2010 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/src/3rdparty/assimp/contrib/zlib/inffast.c b/src/3rdparty/assimp/contrib/zlib/inffast.c deleted file mode 100644 index 2f1d60b43..000000000 --- a/src/3rdparty/assimp/contrib/zlib/inffast.c +++ /dev/null @@ -1,340 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - PUP(out) = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - PUP(out) = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - PUP(out) = PUP(from); - } while (--len); - continue; - } -#endif - } - from = window - OFF; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/src/3rdparty/assimp/contrib/zlib/inffast.h b/src/3rdparty/assimp/contrib/zlib/inffast.h deleted file mode 100644 index e5c1aa4ca..000000000 --- a/src/3rdparty/assimp/contrib/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/src/3rdparty/assimp/contrib/zlib/inffixed.h b/src/3rdparty/assimp/contrib/zlib/inffixed.h deleted file mode 100644 index 75ed4b597..000000000 --- a/src/3rdparty/assimp/contrib/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/src/3rdparty/assimp/contrib/zlib/inflate.c b/src/3rdparty/assimp/contrib/zlib/inflate.c deleted file mode 100644 index a8431abea..000000000 --- a/src/3rdparty/assimp/contrib/zlib/inflate.c +++ /dev/null @@ -1,1480 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - strm->adler = 1; /* to support ill-conceived Java test suite */ - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->window = Z_NULL; - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include <stdio.h> - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - else if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - NEEDBITS(here.bits); - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long id; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - if (state->mode == DICT) { - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->sane = !subvert; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - return Z_OK; -#else - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; - state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} diff --git a/src/3rdparty/assimp/contrib/zlib/inflate.h b/src/3rdparty/assimp/contrib/zlib/inflate.h deleted file mode 100644 index 95f4986d4..000000000 --- a/src/3rdparty/assimp/contrib/zlib/inflate.h +++ /dev/null @@ -1,122 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2009 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 10K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/src/3rdparty/assimp/contrib/zlib/inftrees.c b/src/3rdparty/assimp/contrib/zlib/inftrees.c deleted file mode 100644 index 11e9c52ac..000000000 --- a/src/3rdparty/assimp/contrib/zlib/inftrees.c +++ /dev/null @@ -1,330 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - here.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = here; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/src/3rdparty/assimp/contrib/zlib/inftrees.h b/src/3rdparty/assimp/contrib/zlib/inftrees.h deleted file mode 100644 index baa53a0b1..000000000 --- a/src/3rdparty/assimp/contrib/zlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/src/3rdparty/assimp/contrib/zlib/trees.c b/src/3rdparty/assimp/contrib/zlib/trees.c deleted file mode 100644 index 56e9bb1c1..000000000 --- a/src/3rdparty/assimp/contrib/zlib/trees.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2010 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include <ctype.h> -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1<<extra_lbits[code]); n++) { - _length_code[length++] = (uch)code; - } - } - Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length-1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<<extra_dbits[code]); n++) { - _dist_code[dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include <stdio.h> -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); - } -} - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/src/3rdparty/assimp/contrib/zlib/trees.h b/src/3rdparty/assimp/contrib/zlib/trees.h deleted file mode 100644 index d35639d82..000000000 --- a/src/3rdparty/assimp/contrib/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/src/3rdparty/assimp/contrib/zlib/zconf.h b/src/3rdparty/assimp/contrib/zlib/zconf.h deleted file mode 100644 index 02ce56c43..000000000 --- a/src/3rdparty/assimp/contrib/zlib/zconf.h +++ /dev/null @@ -1,428 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ - -/* all linked symbols */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetHeader z_inflateGetHeader -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# define uncompress z_uncompress -# define zError z_zError -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# define gzFile z_gzFile -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include <windows.h> - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef STDC -# include <sys/types.h> /* for off_t */ -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include <unistd.h> /* for SEEK_* and off_t */ -# ifdef VMS -# include <unixio.h> /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -#endif - -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define z_off64_t off64_t -#else -# define z_off64_t z_off_t -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/src/3rdparty/assimp/contrib/zlib/zconf.in.h b/src/3rdparty/assimp/contrib/zlib/zconf.in.h deleted file mode 100644 index 03a9431c8..000000000 --- a/src/3rdparty/assimp/contrib/zlib/zconf.in.h +++ /dev/null @@ -1,332 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include <windows.h> - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include <sys/types.h> /* for off_t */ -# include <unistd.h> /* for SEEK_* and off_t */ -# ifdef VMS -# include <unixio.h> /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/src/3rdparty/assimp/contrib/zlib/zlib.h b/src/3rdparty/assimp/contrib/zlib/zlib.h deleted file mode 100644 index bfbba83e8..000000000 --- a/src/3rdparty/assimp/contrib/zlib/zlib.h +++ /dev/null @@ -1,1613 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.5, April 19th, 2010 - - Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.5" -#define ZLIB_VERNUM 0x1250 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 5 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all the uncompressed data. (The size - of the uncompressed data may have been saved by the compressor for this - purpose.) The next operation on this stream must be inflateEnd to deallocate - the decompression state. The use of Z_FINISH is never required, but can be - used to inform inflate that a faster approach may be used for the single - inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK or Z_TREES is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been - found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the - success case, the application may save the current current value of total_in - which indicates where valid compressed data was found. In the error case, - the application may repeatedly call inflateSync, providing more input each - time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above or -1 << 16 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef voidp gzFile; /* opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) Also "a" - can be used instead of "w" to request that the gzip stream that will be - written be appended to the file. "+" will result in an error, since reading - and writing to the same gzip file is not supported. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file was not in gzip format, gzread copies the given number of - bytes into the buffer. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream, or failing that, reading the rest - of the input file directly without decompression. The entire input file - will be read if gzread is called until it returns less than the requested - len. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. This state can change from - false to true while reading the input file if the end of a gzip stream is - reached, but is followed by data that is not another gzip stream. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the for the crc. Pre- and post-conditioning (one's - complement) is performed within this function so it shouldn't be done by the - application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# ifdef _LARGEFILE64_SOURCE - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; -#endif - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/src/3rdparty/assimp/contrib/zlib/zutil.c b/src/3rdparty/assimp/contrib/zlib/zutil.c deleted file mode 100644 index 898ed345b..000000000 --- a/src/3rdparty/assimp/contrib/zlib/zutil.c +++ /dev/null @@ -1,318 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#ifdef STDC -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ diff --git a/src/3rdparty/assimp/contrib/zlib/zutil.h b/src/3rdparty/assimp/contrib/zlib/zutil.h deleted file mode 100644 index 258fa8879..000000000 --- a/src/3rdparty/assimp/contrib/zlib/zutil.h +++ /dev/null @@ -1,274 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#ifdef STDC -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include <stddef.h> -# endif -# include <string.h> -# include <stdlib.h> -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include <alloc.h> -# endif -# else /* MSC or DJGPP */ -# include <malloc.h> -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -# ifdef M_I86 -# include <malloc.h> -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include <unix.h> /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - -#if defined(__BORLANDC__) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -#endif -#ifdef VMS -# define NO_vsnprintf -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG -# include <stdio.h> - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); -void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* ZUTIL_H */ diff --git a/src/3rdparty/assimp/include/assimp/Compiler/pushpack1.h b/src/3rdparty/assimp/include/assimp/Compiler/pushpack1.h index 2471b7c1e..a04f3ad12 100644 --- a/src/3rdparty/assimp/include/assimp/Compiler/pushpack1.h +++ b/src/3rdparty/assimp/include/assimp/Compiler/pushpack1.h @@ -8,6 +8,7 @@ // MSVC 7,8,9 // GCC // BORLAND (complains about 'pack state changed but not reverted', but works) +// Clang // // // USAGE: @@ -25,7 +26,11 @@ # pragma pack(push,1) # define PACK_STRUCT #elif defined( __GNUC__ ) -# define PACK_STRUCT __attribute__((packed)) +# if defined(__clang__) +# define PACK_STRUCT __attribute__((__packed__)) +# else +# define PACK_STRUCT __attribute__((gcc_struct, __packed__)) +# endif #else # error Compiler not supported #endif diff --git a/src/3rdparty/assimp/include/assimp/Exporter.hpp b/src/3rdparty/assimp/include/assimp/Exporter.hpp index 662730f8e..55cc068e3 100644 --- a/src/3rdparty/assimp/include/assimp/Exporter.hpp +++ b/src/3rdparty/assimp/include/assimp/Exporter.hpp @@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { class ExporterPimpl; + class IOSystem; // ---------------------------------------------------------------------------------- @@ -167,7 +168,9 @@ public: * @return the exported data or NULL in case of error. * @note If the Exporter instance did already hold a blob from * a previous call to #ExportToBlob, it will be disposed. - * Any IO handlers set via #SetIOHandler are ignored here.*/ + * Any IO handlers set via #SetIOHandler are ignored here. + * @note Use aiCopyScene() to get a modifiable copy of a previously + * imported scene. */ const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u ); inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u ); @@ -195,8 +198,16 @@ public: * redundant as exporters would apply them anyhow. A good example * is triangulation - whilst you can enforce it by specifying * the #aiProcess_Triangulate flag, most export formats support only - * triangulate data so they would run the step even if it wasn't requested. - * @return AI_SUCCESS if everything was fine. */ + * triangulate data so they would run the step even if it wasn't requested. + * + * If assimp detects that the input scene was directly taken from the importer side of + * the library (i.e. not copied using aiCopyScene and potetially modified afterwards), + * any postprocessing steps already applied to the scene will not be applied again, unless + * they show non-idempotent behaviour (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and + * #aiProcess_FlipWindingOrder). + * @return AI_SUCCESS if everything was fine. + * @note Use aiCopyScene() to get a modifiable copy of a previously + * imported scene.*/ aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u); inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u); diff --git a/src/3rdparty/assimp/include/assimp/IOStream.hpp b/src/3rdparty/assimp/include/assimp/IOStream.hpp index 592b157db..a36e65003 100644 --- a/src/3rdparty/assimp/include/assimp/IOStream.hpp +++ b/src/3rdparty/assimp/include/assimp/IOStream.hpp @@ -61,7 +61,10 @@ namespace Assimp { * to the Importer. If you implement this interface, be sure to also provide an * implementation for IOSystem that creates instances of your custom IO class. */ -class ASSIMP_API IOStream : public Intern::AllocateFromAssimpHeap +class ASSIMP_API IOStream +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif { protected: /** Constructor protected, use IOSystem::Open() to create an instance. */ diff --git a/src/3rdparty/assimp/include/assimp/IOSystem.hpp b/src/3rdparty/assimp/include/assimp/IOSystem.hpp index 5854668b1..dfd90b92f 100644 --- a/src/3rdparty/assimp/include/assimp/IOSystem.hpp +++ b/src/3rdparty/assimp/include/assimp/IOSystem.hpp @@ -64,7 +64,10 @@ class IOStream; * supply a custom implementation for IOStream. * * @see Importer::SetIOHandler() */ -class ASSIMP_API IOSystem : public Intern::AllocateFromAssimpHeap +class ASSIMP_API IOSystem +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif { public: diff --git a/src/3rdparty/assimp/include/assimp/Importer.hpp b/src/3rdparty/assimp/include/assimp/Importer.hpp index db127b4d0..20af0725b 100644 --- a/src/3rdparty/assimp/include/assimp/Importer.hpp +++ b/src/3rdparty/assimp/include/assimp/Importer.hpp @@ -231,6 +231,13 @@ public: bool* bWasExisting = NULL); // ------------------------------------------------------------------- + /** Set a matrix configuration property. + * @see SetPropertyInteger() + */ + void SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue, + bool* bWasExisting = NULL); + + // ------------------------------------------------------------------- /** Get a configuration property. * @param szName Name of the property. All supported properties * are defined in the aiConfig.g header (all constants share the @@ -270,10 +277,19 @@ public: * The return value remains valid until the property is modified. * @see GetPropertyInteger() */ - const std::string& GetPropertyString(const char* szName, + const std::string GetPropertyString(const char* szName, const std::string& sErrorReturn = "") const; // ------------------------------------------------------------------- + /** Get a matrix configuration property + * + * The return value remains valid until the property is modified. + * @see GetPropertyInteger() + */ + const aiMatrix4x4 GetPropertyMatrix(const char* szName, + const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const; + + // ------------------------------------------------------------------- /** Supplies a custom IO handler to the importer to use to open and * access files. If you need the importer to use custion IO logic to * access the files, you need to provide a custom implementation of @@ -409,11 +425,12 @@ public: * instance. Use GetOrphanedScene() to take ownership of it. * * @note This is a straightforward way to decode models from memory - * buffers, but it doesn't handle model formats spreading their + * buffers, but it doesn't handle model formats that spread their * data across multiple files or even directories. Examples include - * OBJ or MD3, which outsource parts of their material stuff into - * external scripts. If you need the full functionality, provide - * a custom IOSystem to make Assimp find these files. + * OBJ or MD3, which outsource parts of their material info into + * external scripts. If you need full functionality, provide + * a custom IOSystem to make Assimp find these files and use + * the regular ReadFile() API. */ const aiScene* ReadFileFromMemory( const void* pBuffer, diff --git a/src/3rdparty/assimp/include/assimp/LogStream.hpp b/src/3rdparty/assimp/include/assimp/LogStream.hpp index 8bcb41d3e..2d7731baf 100644 --- a/src/3rdparty/assimp/include/assimp/LogStream.hpp +++ b/src/3rdparty/assimp/include/assimp/LogStream.hpp @@ -53,8 +53,11 @@ class IOSystem; * Several default implementations are provided, see #aiDefaultLogStream for more * details. Writing your own implementation of LogStream is just necessary if these * are not enough for your purpose. */ -class ASSIMP_API LogStream - : public Intern::AllocateFromAssimpHeap { +class ASSIMP_API LogStream +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ protected: /** @brief Default constructor */ LogStream() { diff --git a/src/3rdparty/assimp/include/assimp/Logger.hpp b/src/3rdparty/assimp/include/assimp/Logger.hpp index f780533ee..38bb11790 100644 --- a/src/3rdparty/assimp/include/assimp/Logger.hpp +++ b/src/3rdparty/assimp/include/assimp/Logger.hpp @@ -56,8 +56,11 @@ class LogStream; * Assimp provides a default implementation and uses it for almost all * logging stuff ('DefaultLogger'). This class defines just basic logging * behaviour and is not of interest for you. Instead, take a look at #DefaultLogger. */ -class ASSIMP_API Logger - : public Intern::AllocateFromAssimpHeap { +class ASSIMP_API Logger +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ public: // ---------------------------------------------------------------------- diff --git a/src/3rdparty/assimp/include/assimp/ProgressHandler.hpp b/src/3rdparty/assimp/include/assimp/ProgressHandler.hpp index f2c927d56..a6cddab94 100644 --- a/src/3rdparty/assimp/include/assimp/ProgressHandler.hpp +++ b/src/3rdparty/assimp/include/assimp/ProgressHandler.hpp @@ -51,8 +51,11 @@ namespace Assimp { * * Each #Importer instance maintains its own #ProgressHandler. The default * implementation provided by Assimp doesn't do anything at all. */ -class ASSIMP_API ProgressHandler - : public Intern::AllocateFromAssimpHeap { +class ASSIMP_API ProgressHandler +#ifndef SWIG + : public Intern::AllocateFromAssimpHeap +#endif +{ protected: /** @brief Default constructor */ ProgressHandler () { diff --git a/src/3rdparty/assimp/include/assimp/ai_assert.h b/src/3rdparty/assimp/include/assimp/ai_assert.h index 29ac7a0ec..f42f909d5 100644 --- a/src/3rdparty/assimp/include/assimp/ai_assert.h +++ b/src/3rdparty/assimp/include/assimp/ai_assert.h @@ -3,7 +3,7 @@ #ifndef AI_DEBUG_H_INC #define AI_DEBUG_H_INC -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG # include <assert.h> # define ai_assert(expression) assert(expression) #else diff --git a/src/3rdparty/assimp/include/assimp/anim.h b/src/3rdparty/assimp/include/assimp/anim.h index abc13ba31..2ae1b605b 100644 --- a/src/3rdparty/assimp/include/assimp/anim.h +++ b/src/3rdparty/assimp/include/assimp/anim.h @@ -208,7 +208,7 @@ enum aiAnimBehaviour /** This value is not used, it is just here to force the * the compiler to map this enum to a 32 Bit integer */ #ifndef SWIG - _aiAnimBehaviour_Force32Bit = 0x8fffffff + _aiAnimBehaviour_Force32Bit = INT_MAX #endif }; @@ -457,7 +457,7 @@ struct Interpolator <aiVectorKey> { template <> struct Interpolator <aiQuatKey> { - void operator () (aiQuaternion& out, const aiQuatKey a, + void operator () (aiQuaternion& out, const aiQuatKey& a, const aiQuatKey& b, float d) const { Interpolator<aiQuaternion> ipl; @@ -467,7 +467,7 @@ struct Interpolator <aiQuatKey> { template <> struct Interpolator <aiMeshKey> { - void operator () (unsigned int& out, const aiMeshKey a, + void operator () (unsigned int& out, const aiMeshKey& a, const aiMeshKey& b, float d) const { Interpolator<unsigned int> ipl; diff --git a/src/3rdparty/assimp/include/assimp/cexport.h b/src/3rdparty/assimp/include/assimp/cexport.h index b044dfd25..9041621a1 100644 --- a/src/3rdparty/assimp/include/assimp/cexport.h +++ b/src/3rdparty/assimp/include/assimp/cexport.h @@ -95,16 +95,22 @@ ASSIMP_API const C_STRUCT aiExportFormatDesc* aiGetExportFormatDescription( size // -------------------------------------------------------------------------------- -/** Create a modifyable copy of a scene. +/** Create a modifiable copy of a scene. * This is useful to import files via Assimp, change their topology and * export them again. Since the scene returned by the various importer functions - * is const, a modifyable copy is needed. + * is const, a modifiable copy is needed. * @param pIn Valid scene to be copied - * @param pOut Receives a modifyable copy of the scene. + * @param pOut Receives a modifyable copy of the scene. Use aiFreeScene() to + * delete it again. */ ASSIMP_API void aiCopyScene(const C_STRUCT aiScene* pIn, C_STRUCT aiScene** pOut); + +// -------------------------------------------------------------------------------- +/** Frees a scene copy created using aiCopyScene() */ +ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn); + // -------------------------------------------------------------------------------- /** Exports the given scene to a chosen file format and writes the result file(s) to disk. * @param pScene The scene to export. Stays in possession of the caller, is not changed by the function. @@ -137,7 +143,15 @@ ASSIMP_API void aiCopyScene(const C_STRUCT aiScene* pIn, * is triangulation - whilst you can enforce it by specifying * the #aiProcess_Triangulate flag, most export formats support only * triangulate data so they would run the step anyway. +* +* If assimp detects that the input scene was directly taken from the importer side of +* the library (i.e. not copied using aiCopyScene and potetially modified afterwards), +* any postprocessing steps already applied to the scene will not be applied again, unless +* they show non-idempotent behaviour (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and +* #aiProcess_FlipWindingOrder). * @return a status code indicating the result of the export +* @note Use aiCopyScene() to get a modifiable copy of a previously +* imported scene. */ ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene, const char* pFormatId, @@ -157,6 +171,8 @@ ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene, * @param pPreprocessing Please see the documentation for #aiExportScene * @return a status code indicating the result of the export * @note Include <aiFileIO.h> for the definition of #aiFileIO. +* @note Use aiCopyScene() to get a modifiable copy of a previously +* imported scene. */ ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene, const char* pFormatId, @@ -195,10 +211,10 @@ struct aiExportDataBlob extension that should be used when writing the data to disc. */ - aiString name; + C_STRUCT aiString name; /** Pointer to the next blob in the chain or NULL if there is none. */ - aiExportDataBlob * next; + C_STRUCT aiExportDataBlob * next; #ifdef __cplusplus /// Default constructor @@ -231,7 +247,7 @@ ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const C_STRUCT * returned by aiExportScene(). * @param pData the data blob returned by #aiExportSceneToBlob */ -ASSIMP_API C_STRUCT void aiReleaseExportBlob( const C_STRUCT aiExportDataBlob* pData ); +ASSIMP_API void aiReleaseExportBlob( const C_STRUCT aiExportDataBlob* pData ); #ifdef __cplusplus } diff --git a/src/3rdparty/assimp/include/assimp/cimport.h b/src/3rdparty/assimp/include/assimp/cimport.h index e8593868e..bc2c99e6d 100644 --- a/src/3rdparty/assimp/include/assimp/cimport.h +++ b/src/3rdparty/assimp/include/assimp/cimport.h @@ -79,6 +79,7 @@ struct aiLogStream * @see aiSetPropertyInteger * @see aiSetPropertyFloat * @see aiSetPropertyString + * @see aiSetPropertyMatrix */ // -------------------------------------------------------------------------------- struct aiPropertyStore { char sentinel; }; @@ -170,11 +171,13 @@ ASSIMP_API const C_STRUCT aiScene* aiImportFileExWithProperties( * Check the return value, and you'll know ... * @return A pointer to the imported data, NULL if the import failed. * - * @note This is a straightforward way to decode models from memory buffers, but it - * doesn't handle model formats spreading their data across multiple files or even - * directories. Examples include OBJ or MD3, which outsource parts of their material - * stuff into external scripts. If you need the full functionality, provide a custom - * IOSystem to make Assimp find these files. + * @note This is a straightforward way to decode models from memory + * buffers, but it doesn't handle model formats that spread their + * data across multiple files or even directories. Examples include + * OBJ or MD3, which outsource parts of their material info into + * external scripts. If you need full functionality, provide + * a custom IOSystem to make Assimp find these files and use + * the regular aiImportFileEx()/aiImportFileExWithProperties() API. */ ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemory( const char* pBuffer, @@ -396,6 +399,23 @@ ASSIMP_API void aiSetImportPropertyString( const C_STRUCT aiString* st); // -------------------------------------------------------------------------------- +/** Set a matrix property. + * + * This is the C-version of #Assimp::Importer::SetPropertyMatrix(). In the C + * interface, properties are always shared by all imports. It is not possible to + * specify them per import. + * + * @param property store to modify. Use #aiCreatePropertyStore to obtain a store. + * @param szName Name of the configuration property to be set. All supported + * public properties are defined in the config.h header file (#AI_CONFIG_XXX). + * @param value New value for the property + */ +ASSIMP_API void aiSetImportPropertyMatrix( + C_STRUCT aiPropertyStore* store, + const char* szName, + const C_STRUCT aiMatrix4x4* mat); + +// -------------------------------------------------------------------------------- /** Construct a quaternion from a 3x3 rotation matrix. * @param quat Receives the output quaternion. * @param mat Matrix to 'quaternionize'. diff --git a/src/3rdparty/assimp/include/assimp/color4.h b/src/3rdparty/assimp/include/assimp/color4.h index b6a798f54..52c3c7ec6 100644 --- a/src/3rdparty/assimp/include/assimp/color4.h +++ b/src/3rdparty/assimp/include/assimp/color4.h @@ -74,6 +74,7 @@ public: // comparison bool operator == (const aiColor4t& other) const; bool operator != (const aiColor4t& other) const; + bool operator < (const aiColor4t& other) const; // color tuple access, rgba order inline TReal operator[](unsigned int i) const; diff --git a/src/3rdparty/assimp/include/assimp/color4.inl b/src/3rdparty/assimp/include/assimp/color4.inl index 1e30b8ed1..9a92e1412 100644 --- a/src/3rdparty/assimp/include/assimp/color4.inl +++ b/src/3rdparty/assimp/include/assimp/color4.inl @@ -94,6 +94,23 @@ AI_FORCE_INLINE bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other } // ------------------------------------------------------------------------------------------------ template <typename TReal> +AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const { + return r < other.r || ( + r == other.r && ( + g < other.g || ( + g == other.g && ( + b < other.b || ( + b == other.b && ( + a < other.a + ) + ) + ) + ) + ) + ); +} +// ------------------------------------------------------------------------------------------------ +template <typename TReal> AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) { return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a); } diff --git a/src/3rdparty/assimp/include/assimp/config.h b/src/3rdparty/assimp/include/assimp/config.h index 63075bdb2..941f3c1cc 100644 --- a/src/3rdparty/assimp/include/assimp/config.h +++ b/src/3rdparty/assimp/include/assimp/config.h @@ -77,6 +77,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_CONFIG_GLOB_MEASURE_TIME \ "GLOB_MEASURE_TIME" + +// --------------------------------------------------------------------------- +/** @brief Global setting to disable generation of skeleton dummy meshes + * + * Skeleton dummy meshes are generated as a visualization aid in cases which + * the input data contains no geometry, but only animation data. + * Property data type: bool. Default value: false + */ +// --------------------------------------------------------------------------- +#define AI_CONFIG_IMPORT_NO_SKELETON_MESHES \ + "IMPORT_NO_SKELETON_MESHES" + + + # if 0 // not implemented yet // --------------------------------------------------------------------------- /** @brief Set Assimp's multithreading policy. @@ -158,6 +172,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE \ "PP_GSN_MAX_SMOOTHING_ANGLE" + // --------------------------------------------------------------------------- /** @brief Sets the colormap (= palette) to be used to decode embedded * textures in MDL (Quake or 3DGS) files. @@ -219,6 +234,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. "PP_PTV_NORMALIZE" // --------------------------------------------------------------------------- +/** @brief Configures the #aiProcess_PretransformVertices step to use + * a users defined matrix as the scene root node transformation before + * transforming vertices. + * Property type: bool. Default value: false. + */ +#define AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION \ + "PP_PTV_ADD_ROOT_TRANSFORMATION" + +// --------------------------------------------------------------------------- +/** @brief Configures the #aiProcess_PretransformVertices step to use + * a users defined matrix as the scene root node transformation before + * transforming vertices. This property correspond to the 'a1' component + * of the transformation matrix. + * Property type: aiMatrix4x4. + */ +#define AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION \ + "PP_PTV_ROOT_TRANSFORMATION" + +// --------------------------------------------------------------------------- /** @brief Configures the #aiProcess_FindDegenerates step to * remove degenerated primitives from the import - immediately. * @@ -388,7 +422,7 @@ enum aiComponent * use the #aiProcess_OptimizeGraph step to do this */ aiComponent_LIGHTS = 0x100, - /** Removes all light sources (aiScene::mCameras). + /** Removes all cameras (aiScene::mCameras). * The corresponding scenegraph nodes are NOT removed. * use the #aiProcess_OptimizeGraph step to do this */ aiComponent_CAMERAS = 0x200, @@ -497,6 +531,100 @@ enum aiComponent // --------------------------------------------------------------------------- +/** @brief Set whether the fbx importer will merge all geometry layers present + * in the source file or take only the first. + * + * The default value is true (1) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS \ + "IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS" + +// --------------------------------------------------------------------------- +/** @brief Set whether the fbx importer will read all materials present in the + * source file or take only the referenced materials. + * + * This is void unless IMPORT_FBX_READ_MATERIALS=1. + * + * The default value is false (0) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS \ + "IMPORT_FBX_READ_ALL_MATERIALS" + +// --------------------------------------------------------------------------- +/** @brief Set whether the fbx importer will read materials. + * + * The default value is true (1) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_READ_MATERIALS \ + "IMPORT_FBX_READ_MATERIALS" + +// --------------------------------------------------------------------------- +/** @brief Set whether the fbx importer will read cameras. + * + * The default value is true (1) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_READ_CAMERAS \ + "IMPORT_FBX_READ_CAMERAS" + +// --------------------------------------------------------------------------- +/** @brief Set whether the fbx importer will read light sources. + * + * The default value is true (1) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_READ_LIGHTS \ + "IMPORT_FBX_READ_LIGHTS" + +// --------------------------------------------------------------------------- +/** @brief Set whether the fbx importer will read animations. + * + * The default value is true (1) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS \ + "IMPORT_FBX_READ_ANIMATIONS" + +// --------------------------------------------------------------------------- +/** @brief Set whether the fbx importer will act in strict mode in which only + * FBX 2013 is supported and any other sub formats are rejected. FBX 2013 + * is the primary target for the importer, so this format is best + * supported and well-tested. + * + * The default value is false (0) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_STRICT_MODE \ + "IMPORT_FBX_STRICT_MODE" + +// --------------------------------------------------------------------------- +/** @brief Set whether the fbx importer will preserve pivot points for + * transformations (as extra nodes). If set to false, pivots and offsets + * will be evaluated whenever possible. + * + * The default value is true (1) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS \ + "IMPORT_FBX_PRESERVE_PIVOTS" + +// --------------------------------------------------------------------------- +/** @brief Specifies whether the importer will drop empty animation curves or + * animation curves which match the bind pose transformation over their + * entire defined range. + * + * The default value is true (1) + * Property type: bool + */ +#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \ + "IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES" + + + +// --------------------------------------------------------------------------- /** @brief Set the vertex animation keyframe to be imported * * ASSIMP does not support vertex keyframes (only bone animation is supported). @@ -673,33 +801,38 @@ enum aiComponent #define AI_CONFIG_IMPORT_IRR_ANIM_FPS \ "IMPORT_IRR_ANIM_FPS" - // --------------------------------------------------------------------------- -/** @brief Ogre Importer will try to load this Materialfile. +/** @brief Ogre Importer will try to find referenced materials from this file. * - * Ogre Meshes contain only the MaterialName, not the MaterialFile. If there - * is no material file with the same name as the material, Ogre Importer will - * try to load this file and search the material in it. + * Ogre meshes reference with material names, this does not tell Assimp the file + * where it is located in. Assimp will try to find the source file in the following + * order: <material-name>.material, <mesh-filename-base>.material and + * lastly the material name defined by this config property. * <br> - * Property type: String. Default value: guessed. + * Property type: String. Default value: Scene.material. */ -#define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE "IMPORT_OGRE_MATERIAL_FILE" - +#define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE \ + "IMPORT_OGRE_MATERIAL_FILE" // --------------------------------------------------------------------------- -/** @brief Ogre Importer detect the texture usage from its filename +/** @brief Ogre Importer detect the texture usage from its filename. * - * Normally, a texture is loaded as a colormap, if no target is specified in the - * materialfile. Is this switch is enabled, texture names ending with _n, _l, _s - * are used as normalmaps, lightmaps or specularmaps. + * Ogre material texture units do not define texture type, the textures usage + * depends on the used shader or Ogres fixed pipeline. If this config property + * is true Assimp will try to detect the type from the textures filename postfix: + * _n, _nrm, _nrml, _normal, _normals and _normalmap for normal map, _s, _spec, + * _specular and _specularmap for specular map, _l, _light, _lightmap, _occ + * and _occlusion for light map, _disp and _displacement for displacement map. + * The matching is case insensitive. Post fix is taken between last "_" and last ".". + * Default behavior is to detect type from lower cased texture unit name by + * matching against: normalmap, specularmap, lightmap and displacementmap. + * For both cases if no match is found aiTextureType_DIFFUSE is used. * <br> * Property type: Bool. Default value: false. */ -#define AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME "IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME" - +#define AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME \ + "IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME" - -// --------------------------------------------------------------------------- /** @brief Specifies whether the IFC loader skips over IfcSpace elements. * * IfcSpace elements (and their geometric representations) are used to @@ -735,4 +868,6 @@ enum aiComponent */ #define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION" +#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION" + #endif // !! AI_CONFIG_H_INC diff --git a/src/3rdparty/assimp/include/assimp/defs.h b/src/3rdparty/assimp/include/assimp/defs.h index ad063984b..b1f0b9839 100644 --- a/src/3rdparty/assimp/include/assimp/defs.h +++ b/src/3rdparty/assimp/include/assimp/defs.h @@ -60,9 +60,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Other (mixed) configuration switches are listed here: * ASSIMP_BUILD_NO_COMPRESSED_X - * - Disable support for compressed X files + * - Disable support for compressed X files (zip) * ASSIMP_BUILD_NO_COMPRESSED_BLEND - * - Disable support for compressed Blender files*/ + * - Disable support for compressed Blender files (zip) + * ASSIMP_BUILD_NO_COMPRESSED_IFC + * - Disable support for IFCZIP files (unzip) + */ ////////////////////////////////////////////////////////////////////////// #ifndef ASSIMP_BUILD_NO_COMPRESSED_X @@ -73,6 +76,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # define ASSIMP_BUILD_NEED_Z_INFLATE #endif +#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC +# define ASSIMP_BUILD_NEED_Z_INFLATE +# define ASSIMP_BUILD_NEED_UNZIP +#endif + +#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER +# define ASSIMP_BUILD_NEED_Z_INFLATE +# define ASSIMP_BUILD_NEED_UNZIP +#endif + ////////////////////////////////////////////////////////////////////////// /* Define ASSIMP_BUILD_NO_XX_PROCESS to disable a specific * post processing step. This is the current list of process names ('XX'): @@ -135,6 +148,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* Tells the compiler that a function never returns. Used in code analysis * to skip dead paths (e.g. after an assertion evaluated to false). */ # define AI_WONT_RETURN __declspec(noreturn) + +#elif defined(SWIG) + + /* Do nothing, the relevant defines are all in AssimpSwigPort.i */ + #else # define AI_WONT_RETURN @@ -144,6 +162,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # define AI_FORCE_INLINE inline #endif // (defined _MSC_VER) +#ifdef __clang__ +# define AI_WONT_RETURN_SUFFIX __attribute__((analyzer_noreturn)) +#else +# define AI_WONT_RETURN_SUFFIX +#endif // (defined __clang__) + #ifdef __cplusplus /* No explicit 'struct' and 'enum' tags for C++, this keeps showing up * in doxydocs. @@ -214,11 +238,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # define ASSIMP_BUILD_SINGLETHREADED #endif -#ifndef ASSIMP_BUILD_SINGLETHREADED -# define AI_C_THREADSAFE -#endif // !! ASSIMP_BUILD_SINGLETHREADED - -#ifdef _DEBUG +#if defined(_DEBUG) || ! defined(NDEBUG) # define ASSIMP_BUILD_DEBUG #endif diff --git a/src/3rdparty/assimp/include/assimp/light.h b/src/3rdparty/assimp/include/assimp/light.h index 64a21aa85..81aceccf4 100644 --- a/src/3rdparty/assimp/include/assimp/light.h +++ b/src/3rdparty/assimp/include/assimp/light.h @@ -80,7 +80,7 @@ enum aiLightSourceType * compiler to map this enum to a 32 Bit integer. */ #ifndef SWIG - _aiLightSource_Force32Bit = 0x9fffffff + _aiLightSource_Force32Bit = INT_MAX #endif }; diff --git a/src/3rdparty/assimp/include/assimp/material.h b/src/3rdparty/assimp/include/assimp/material.h index 39844deb0..daf6a8e09 100644 --- a/src/3rdparty/assimp/include/assimp/material.h +++ b/src/3rdparty/assimp/include/assimp/material.h @@ -100,7 +100,7 @@ enum aiTextureOp * 32 Bit integers to represent this enum. */ #ifndef SWIG - _aiTextureOp_Force32Bit = 0x9fffffff + _aiTextureOp_Force32Bit = INT_MAX #endif //! @endcond }; @@ -136,7 +136,7 @@ enum aiTextureMapMode * 32 Bit integers to represent this enum. */ #ifndef SWIG - _aiTextureMapMode_Force32Bit = 0x9fffffff + _aiTextureMapMode_Force32Bit = INT_MAX #endif //! @endcond }; @@ -181,7 +181,7 @@ enum aiTextureMapping * 32 Bit integers to represent this enum. */ #ifndef SWIG - _aiTextureMapping_Force32Bit = 0x9fffffff + _aiTextureMapping_Force32Bit = INT_MAX #endif //! @endcond }; @@ -301,7 +301,7 @@ enum aiTextureType * 32 Bit integers to represent this enum. */ #ifndef SWIG - _aiTextureType_Force32Bit = 0x9fffffff + _aiTextureType_Force32Bit = INT_MAX #endif //! @endcond }; @@ -379,7 +379,7 @@ enum aiShadingMode * 32 Bit integers to represent this enum. */ #ifndef SWIG - _aiShadingMode_Force32Bit = 0x9fffffff + _aiShadingMode_Force32Bit = INT_MAX #endif //! @endcond }; @@ -425,7 +425,7 @@ enum aiTextureFlags * 32 Bit integers to represent this enum. */ #ifndef SWIG - _aiTextureFlags_Force32Bit = 0x9fffffff + _aiTextureFlags_Force32Bit = INT_MAX #endif //! @endcond }; @@ -474,7 +474,7 @@ enum aiBlendMode * 32 Bit integers to represent this enum. */ #ifndef SWIG - _aiBlendMode_Force32Bit = 0x9fffffff + _aiBlendMode_Force32Bit = INT_MAX #endif //! @endcond }; @@ -568,7 +568,7 @@ enum aiPropertyTypeInfo * compiler to map this enum to a 32 Bit integer. */ #ifndef SWIG - _aiPTI_Force32Bit = 0x9fffffff + _aiPTI_Force32Bit = INT_MAX #endif }; @@ -631,9 +631,13 @@ struct aiMaterialProperty #ifdef __cplusplus - aiMaterialProperty() { - mData = NULL; - mIndex = mSemantic = 0; + aiMaterialProperty() + : mSemantic( 0 ) + , mIndex( 0 ) + , mDataLength( 0 ) + , mType( aiPTI_Float ) + , mData( NULL ) + { } ~aiMaterialProperty() { @@ -657,7 +661,11 @@ struct aiMaterialProperty * have to stick with the aiMaterialGetXXX family of unbound functions. * The library defines a set of standard keys (AI_MATKEY_XXX). */ +#ifdef __cplusplus struct ASSIMP_API aiMaterial +#else +struct aiMaterial +#endif { #ifdef __cplusplus @@ -683,6 +691,12 @@ public: aiReturn Get(const char* pKey,unsigned int type, unsigned int idx, Type* pOut, unsigned int* pMax) const; + aiReturn Get(const char* pKey,unsigned int type, + unsigned int idx, int* pOut, unsigned int* pMax) const; + + aiReturn Get(const char* pKey,unsigned int type, + unsigned int idx, float* pOut, unsigned int* pMax) const; + // ------------------------------------------------------------------- /** @brief Retrieve a Type value with a specific key * from the material @@ -697,6 +711,25 @@ public: aiReturn Get(const char* pKey,unsigned int type, unsigned int idx,Type& pOut) const; + + aiReturn Get(const char* pKey,unsigned int type, + unsigned int idx, int& pOut) const; + + aiReturn Get(const char* pKey,unsigned int type, + unsigned int idx, float& pOut) const; + + aiReturn Get(const char* pKey,unsigned int type, + unsigned int idx, aiString& pOut) const; + + aiReturn Get(const char* pKey,unsigned int type, + unsigned int idx, aiColor3D& pOut) const; + + aiReturn Get(const char* pKey,unsigned int type, + unsigned int idx, aiColor4D& pOut) const; + + aiReturn Get(const char* pKey,unsigned int type, + unsigned int idx, aiUVTransform& pOut) const; + // ------------------------------------------------------------------- /** Get the number of textures for a particular texture type. * @param type Texture type to check for @@ -789,6 +822,42 @@ public: unsigned int type = 0, unsigned int index = 0); + aiReturn AddProperty (const aiVector3D* pInput, + unsigned int pNumValues, + const char* pKey, + unsigned int type = 0, + unsigned int index = 0); + + aiReturn AddProperty (const aiColor3D* pInput, + unsigned int pNumValues, + const char* pKey, + unsigned int type = 0, + unsigned int index = 0); + + aiReturn AddProperty (const aiColor4D* pInput, + unsigned int pNumValues, + const char* pKey, + unsigned int type = 0, + unsigned int index = 0); + + aiReturn AddProperty (const int* pInput, + unsigned int pNumValues, + const char* pKey, + unsigned int type = 0, + unsigned int index = 0); + + aiReturn AddProperty (const float* pInput, + unsigned int pNumValues, + const char* pKey, + unsigned int type = 0, + unsigned int index = 0); + + aiReturn AddProperty (const aiUVTransform* pInput, + unsigned int pNumValues, + const char* pKey, + unsigned int type = 0, + unsigned int index = 0); + // ------------------------------------------------------------------------------ /** @brief Remove a given key from the list. * @@ -1405,6 +1474,18 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat, // --------------------------------------------------------------------------- +/** @brief Retrieve a aiUVTransform value from the material property table +* +* See the sample for aiGetMaterialFloat for more information*/ +// --------------------------------------------------------------------------- +ASSIMP_API C_ENUM aiReturn aiGetMaterialUVTransform(const C_STRUCT aiMaterial* pMat, + const char* pKey, + unsigned int type, + unsigned int index, + C_STRUCT aiUVTransform* pOut); + + +// --------------------------------------------------------------------------- /** @brief Retrieve a string from the material property table * * See the sample for aiGetMaterialFloat for more information.*/ diff --git a/src/3rdparty/assimp/include/assimp/material.inl b/src/3rdparty/assimp/include/assimp/material.inl index 305208366..64d5b749b 100644 --- a/src/3rdparty/assimp/include/assimp/material.inl +++ b/src/3rdparty/assimp/include/assimp/material.inl @@ -89,7 +89,7 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, } iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type)); - memcpy(pOut,prop->mData,iNum * sizeof(Type)); + ::memcpy(pOut,prop->mData,iNum * sizeof(Type)); if (pMax) { *pMax = iNum; } @@ -115,51 +115,45 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, return AI_FAILURE; } - memcpy(&pOut,prop->mData,sizeof(Type)); + ::memcpy(&pOut,prop->mData,sizeof(Type)); } return ret; } // --------------------------------------------------------------------------- -template <> -inline aiReturn aiMaterial::Get<float>(const char* pKey,unsigned int type, +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, unsigned int idx,float* pOut, unsigned int* pMax) const { return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax); } // --------------------------------------------------------------------------- -template <> -inline aiReturn aiMaterial::Get<int>(const char* pKey,unsigned int type, +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, unsigned int idx,int* pOut, unsigned int* pMax) const { return ::aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax); } // --------------------------------------------------------------------------- -template <> -inline aiReturn aiMaterial::Get<float>(const char* pKey,unsigned int type, +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, unsigned int idx,float& pOut) const { return aiGetMaterialFloat(this,pKey,type,idx,&pOut); } // --------------------------------------------------------------------------- -template <> -inline aiReturn aiMaterial::Get<int>(const char* pKey,unsigned int type, +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, unsigned int idx,int& pOut) const { return aiGetMaterialInteger(this,pKey,type,idx,&pOut); } // --------------------------------------------------------------------------- -template <> -inline aiReturn aiMaterial::Get<aiColor4D>(const char* pKey,unsigned int type, +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, unsigned int idx,aiColor4D& pOut) const { return aiGetMaterialColor(this,pKey,type,idx,&pOut); } // --------------------------------------------------------------------------- -template <> -inline aiReturn aiMaterial::Get<aiColor3D>(const char* pKey,unsigned int type, +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, unsigned int idx,aiColor3D& pOut) const { aiColor4D c; @@ -168,16 +162,19 @@ inline aiReturn aiMaterial::Get<aiColor3D>(const char* pKey,unsigned int type, return ret; } // --------------------------------------------------------------------------- -template <> -inline aiReturn aiMaterial::Get<aiString>(const char* pKey,unsigned int type, +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, unsigned int idx,aiString& pOut) const { return aiGetMaterialString(this,pKey,type,idx,&pOut); } +// --------------------------------------------------------------------------- +inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, + unsigned int idx,aiUVTransform& pOut) const +{ + return aiGetMaterialUVTransform(this,pKey,type,idx,&pOut); +} -#ifndef ASSIMP_BUILD_NO_EXPORT - // --------------------------------------------------------------------------- template<class TYPE> aiReturn aiMaterial::AddProperty (const TYPE* pInput, @@ -192,8 +189,87 @@ aiReturn aiMaterial::AddProperty (const TYPE* pInput, } // --------------------------------------------------------------------------- +inline aiReturn aiMaterial::AddProperty(const float* pInput, + const unsigned int pNumValues, + const char* pKey, + unsigned int type, + unsigned int index) +{ + return AddBinaryProperty((const void*)pInput, + pNumValues * sizeof(float), + pKey,type,index,aiPTI_Float); +} + +// --------------------------------------------------------------------------- +inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput, + const unsigned int pNumValues, + const char* pKey, + unsigned int type, + unsigned int index) +{ + return AddBinaryProperty((const void*)pInput, + pNumValues * sizeof(aiUVTransform), + pKey,type,index,aiPTI_Float); +} + +// --------------------------------------------------------------------------- +inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput, + const unsigned int pNumValues, + const char* pKey, + unsigned int type, + unsigned int index) +{ + return AddBinaryProperty((const void*)pInput, + pNumValues * sizeof(aiColor4D), + pKey,type,index,aiPTI_Float); +} + +// --------------------------------------------------------------------------- +inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput, + const unsigned int pNumValues, + const char* pKey, + unsigned int type, + unsigned int index) +{ + return AddBinaryProperty((const void*)pInput, + pNumValues * sizeof(aiColor3D), + pKey,type,index,aiPTI_Float); +} + +// --------------------------------------------------------------------------- +inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput, + const unsigned int pNumValues, + const char* pKey, + unsigned int type, + unsigned int index) +{ + return AddBinaryProperty((const void*)pInput, + pNumValues * sizeof(aiVector3D), + pKey,type,index,aiPTI_Float); +} + +// --------------------------------------------------------------------------- +inline aiReturn aiMaterial::AddProperty(const int* pInput, + const unsigned int pNumValues, + const char* pKey, + unsigned int type, + unsigned int index) +{ + return AddBinaryProperty((const void*)pInput, + pNumValues * sizeof(int), + pKey,type,index,aiPTI_Integer); +} + + +// --------------------------------------------------------------------------- +// The template specializations below are for backwards compatibility. +// The recommended way to add material properties is using the non-template +// overloads. +// --------------------------------------------------------------------------- + +// --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<float> (const float* pInput, +inline aiReturn aiMaterial::AddProperty<float>(const float* pInput, const unsigned int pNumValues, const char* pKey, unsigned int type, @@ -206,7 +282,7 @@ inline aiReturn aiMaterial::AddProperty<float> (const float* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<aiUVTransform> (const aiUVTransform* pInput, +inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput, const unsigned int pNumValues, const char* pKey, unsigned int type, @@ -219,7 +295,7 @@ inline aiReturn aiMaterial::AddProperty<aiUVTransform> (const aiUVTransform* pIn // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<aiColor4D> (const aiColor4D* pInput, +inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput, const unsigned int pNumValues, const char* pKey, unsigned int type, @@ -232,7 +308,7 @@ inline aiReturn aiMaterial::AddProperty<aiColor4D> (const aiColor4D* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<aiColor3D> (const aiColor3D* pInput, +inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput, const unsigned int pNumValues, const char* pKey, unsigned int type, @@ -245,7 +321,7 @@ inline aiReturn aiMaterial::AddProperty<aiColor3D> (const aiColor3D* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<aiVector3D> (const aiVector3D* pInput, +inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput, const unsigned int pNumValues, const char* pKey, unsigned int type, @@ -258,7 +334,7 @@ inline aiReturn aiMaterial::AddProperty<aiVector3D> (const aiVector3D* pInput, // --------------------------------------------------------------------------- template<> -inline aiReturn aiMaterial::AddProperty<int> (const int* pInput, +inline aiReturn aiMaterial::AddProperty<int>(const int* pInput, const unsigned int pNumValues, const char* pKey, unsigned int type, @@ -269,8 +345,6 @@ inline aiReturn aiMaterial::AddProperty<int> (const int* pInput, pKey,type,index,aiPTI_Integer); } -#endif - //! @endcond #endif //! AI_MATERIAL_INL_INC diff --git a/src/3rdparty/assimp/include/assimp/matrix3x3.h b/src/3rdparty/assimp/include/assimp/matrix3x3.h index 500cb9eff..0cff32157 100644 --- a/src/3rdparty/assimp/include/assimp/matrix3x3.h +++ b/src/3rdparty/assimp/include/assimp/matrix3x3.h @@ -90,8 +90,10 @@ public: const TReal* operator[] (unsigned int p_iIndex) const; // comparison operators - bool operator== (const aiMatrix4x4t<TReal> m) const; - bool operator!= (const aiMatrix4x4t<TReal> m) const; + bool operator== (const aiMatrix4x4t<TReal>& m) const; + bool operator!= (const aiMatrix4x4t<TReal>& m) const; + + bool Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon = 1e-6) const; template <typename TOther> operator aiMatrix3x3t<TOther> () const; diff --git a/src/3rdparty/assimp/include/assimp/matrix3x3.inl b/src/3rdparty/assimp/include/assimp/matrix3x3.inl index 9a21595ed..56cac6cd1 100644 --- a/src/3rdparty/assimp/include/assimp/matrix3x3.inl +++ b/src/3rdparty/assimp/include/assimp/matrix3x3.inl @@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "matrix4x4.h" #include <algorithm> +#include <cmath> #include <limits> // ------------------------------------------------------------------------------------------------ @@ -113,7 +114,7 @@ inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) cons // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const +inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const { return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && @@ -122,11 +123,26 @@ inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const // ------------------------------------------------------------------------------------------------ template <typename TReal> -inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const +inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const { return !(*this == m); } +// --------------------------------------------------------------------------- +template<typename TReal> +inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const { + return + std::abs(a1 - m.a1) <= epsilon && + std::abs(a2 - m.a2) <= epsilon && + std::abs(a3 - m.a3) <= epsilon && + std::abs(b1 - m.b1) <= epsilon && + std::abs(b2 - m.b2) <= epsilon && + std::abs(b3 - m.b3) <= epsilon && + std::abs(c1 - m.c1) <= epsilon && + std::abs(c2 - m.c2) <= epsilon && + std::abs(c3 - m.c3) <= epsilon; +} + // ------------------------------------------------------------------------------------------------ template <typename TReal> inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose() diff --git a/src/3rdparty/assimp/include/assimp/matrix4x4.h b/src/3rdparty/assimp/include/assimp/matrix4x4.h index d00e158c0..3d0857fe6 100644 --- a/src/3rdparty/assimp/include/assimp/matrix4x4.h +++ b/src/3rdparty/assimp/include/assimp/matrix4x4.h @@ -78,6 +78,14 @@ public: /** construction from 3x3 matrix, remaining elements are set to identity */ explicit aiMatrix4x4t( const aiMatrix3x3t<TReal>& m); + + /** construction from position, rotation and scaling components + * @param scaling The scaling for the x,y,z axes + * @param rotation The rotation as a hamilton quaternion + * @param position The position for the x,y,z axes + */ + aiMatrix4x4t(aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation, + aiVector3t<TReal>& position); public: @@ -86,8 +94,10 @@ public: const TReal* operator[] (unsigned int p_iIndex) const; // comparison operators - bool operator== (const aiMatrix4x4t m) const; - bool operator!= (const aiMatrix4x4t m) const; + bool operator== (const aiMatrix4x4t& m) const; + bool operator!= (const aiMatrix4x4t& m) const; + + bool Equal(const aiMatrix4x4t& m, TReal epsilon = 1e-6) const; // matrix multiplication. aiMatrix4x4t& operator *= (const aiMatrix4x4t& m); diff --git a/src/3rdparty/assimp/include/assimp/matrix4x4.inl b/src/3rdparty/assimp/include/assimp/matrix4x4.inl index 3cddb3ab8..4697d77b6 100644 --- a/src/3rdparty/assimp/include/assimp/matrix4x4.inl +++ b/src/3rdparty/assimp/include/assimp/matrix4x4.inl @@ -7,8 +7,8 @@ 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 +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 @@ -25,16 +25,16 @@ conditions are met: 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 +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 +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 +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 +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. --------------------------------------------------------------------------- */ @@ -53,13 +53,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <algorithm> #include <limits> -#include <math.h> + +#ifdef __cplusplus +# include <cmath> +#else +# include <math.h> +#endif // ---------------------------------------------------------------------------------------- template <typename TReal> -aiMatrix4x4t<TReal> ::aiMatrix4x4t () : - a1(1.0f), a2(), a3(), a4(), - b1(), b2(1.0f), b3(), b4(), +aiMatrix4x4t<TReal> ::aiMatrix4x4t () : + a1(1.0f), a2(), a3(), a4(), + b1(), b2(1.0f), b3(), b4(), c1(), c2(), c3(1.0f), c4(), d1(), d2(), d3(), d4(1.0f) { @@ -71,13 +76,13 @@ template <typename TReal> aiMatrix4x4t<TReal> ::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4, TReal _b1, TReal _b2, TReal _b3, TReal _b4, TReal _c1, TReal _c2, TReal _c3, TReal _c4, - TReal _d1, TReal _d2, TReal _d3, TReal _d4) : - a1(_a1), a2(_a2), a3(_a3), a4(_a4), - b1(_b1), b2(_b2), b3(_b3), b4(_b4), + TReal _d1, TReal _d2, TReal _d3, TReal _d4) : + a1(_a1), a2(_a2), a3(_a3), a4(_a4), + b1(_b1), b2(_b2), b3(_b3), b4(_b4), c1(_c1), c2(_c2), c3(_c3), c4(_c4), d1(_d1), d2(_d2), d3(_d3), d4(_d4) { - + } // ------------------------------------------------------------------------------------------------ @@ -104,6 +109,34 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m) // ---------------------------------------------------------------------------------------- template <typename TReal> +inline aiMatrix4x4t<TReal>::aiMatrix4x4t (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation, aiVector3t<TReal>& position) +{ + // build a 3x3 rotation matrix + aiMatrix3x3t<TReal> m = rotation.GetMatrix(); + + a1 = m.a1 * scaling.x; + a2 = m.a2 * scaling.x; + a3 = m.a3 * scaling.x; + a4 = position.x; + + b1 = m.b1 * scaling.y; + b2 = m.b2 * scaling.y; + b3 = m.b3 * scaling.y; + b4 = position.y; + + c1 = m.c1 * scaling.z; + c2 = m.c2 * scaling.z; + c3 = m.c3 * scaling.z; + c4= position.z; + + d1 = static_cast<TReal>(0.0); + d2 = static_cast<TReal>(0.0); + d3 = static_cast<TReal>(0.0); + d4 = static_cast<TReal>(1.0); +} + +// ---------------------------------------------------------------------------------------- +template <typename TReal> inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m) { *this = aiMatrix4x4t<TReal>( @@ -155,10 +188,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose() template <typename TReal> inline TReal aiMatrix4x4t<TReal>::Determinant() const { - return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4 - + a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4 - - a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3 - + a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2 + return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4 + + a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4 + - a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3 + + a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2 + a3*b2*c4*d1 - a3*b2*c1*d4 - a4*b1*c2*d3 + a4*b1*c3*d2 - a4*b2*c3*d1 + a4*b2*c1*d3 - a4*b3*c1*d2 + a4*b3*c2*d1; } @@ -169,7 +202,7 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() { // Compute the reciprocal determinant const TReal det = Determinant(); - if(det == static_cast<TReal>(0.0)) + if(det == static_cast<TReal>(0.0)) { // Matrix not invertible. Setting all elements to nan is not really // correct in a mathematical sense but it is easy to debug for the @@ -202,7 +235,7 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() res.d1 = -invdet * (b1 * (c2 * d3 - c3 * d2) + b2 * (c3 * d1 - c1 * d3) + b3 * (c1 * d2 - c2 * d1)); res.d2 = invdet * (a1 * (c2 * d3 - c3 * d2) + a2 * (c3 * d1 - c1 * d3) + a3 * (c1 * d2 - c2 * d1)); res.d3 = -invdet * (a1 * (b2 * d3 - b3 * d2) + a2 * (b3 * d1 - b1 * d3) + a3 * (b1 * d2 - b2 * d1)); - res.d4 = invdet * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1)); + res.d4 = invdet * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1)); *this = res; return *this; @@ -226,7 +259,7 @@ inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const // ---------------------------------------------------------------------------------------- template <typename TReal> -inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const +inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const { return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 && b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 && @@ -236,11 +269,33 @@ inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal> m) const // ---------------------------------------------------------------------------------------- template <typename TReal> -inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal> m) const +inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const { return !(*this == m); } +// --------------------------------------------------------------------------- +template<typename TReal> +inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const { + return + std::abs(a1 - m.a1) <= epsilon && + std::abs(a2 - m.a2) <= epsilon && + std::abs(a3 - m.a3) <= epsilon && + std::abs(a4 - m.a4) <= epsilon && + std::abs(b1 - m.b1) <= epsilon && + std::abs(b2 - m.b2) <= epsilon && + std::abs(b3 - m.b3) <= epsilon && + std::abs(b4 - m.b4) <= epsilon && + std::abs(c1 - m.c1) <= epsilon && + std::abs(c2 - m.c2) <= epsilon && + std::abs(c3 - m.c3) <= epsilon && + std::abs(c4 - m.c4) <= epsilon && + std::abs(d1 - m.d1) <= epsilon && + std::abs(d2 - m.d2) <= epsilon && + std::abs(d3 - m.d3) <= epsilon && + std::abs(d4 - m.d4) <= epsilon; +} + // ---------------------------------------------------------------------------------------- template <typename TReal> inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation, @@ -368,9 +423,9 @@ inline bool aiMatrix4x4t<TReal>::IsIdentity() const d1 <= epsilon && d1 >= -epsilon && d2 <= epsilon && d2 >= -epsilon && d3 <= epsilon && d3 >= -epsilon && - a1 <= 1.f+epsilon && a1 >= 1.f-epsilon && - b2 <= 1.f+epsilon && b2 >= 1.f-epsilon && - c3 <= 1.f+epsilon && c3 >= 1.f-epsilon && + a1 <= 1.f+epsilon && a1 >= 1.f-epsilon && + b2 <= 1.f+epsilon && b2 >= 1.f-epsilon && + c3 <= 1.f+epsilon && c3 >= 1.f-epsilon && d4 <= 1.f+epsilon && d4 >= 1.f-epsilon); } @@ -472,9 +527,9 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal */ // ---------------------------------------------------------------------------------------- template <typename TReal> -inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, +inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from, const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx) -{ +{ aiMatrix3x3t<TReal> m3; aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3); mtx = aiMatrix4x4t<TReal>(m3); diff --git a/src/3rdparty/assimp/include/assimp/mesh.h b/src/3rdparty/assimp/include/assimp/mesh.h index 0f867fe77..9e82608a0 100644 --- a/src/3rdparty/assimp/include/assimp/mesh.h +++ b/src/3rdparty/assimp/include/assimp/mesh.h @@ -135,8 +135,9 @@ struct aiFace //! Default constructor aiFace() + : mNumIndices( 0 ) + , mIndices( NULL ) { - mNumIndices = 0; mIndices = NULL; } //! Default destructor. Delete the index array @@ -147,21 +148,26 @@ struct aiFace //! Copy constructor. Copy the index array aiFace( const aiFace& o) + : mIndices( NULL ) { - mIndices = NULL; *this = o; } //! Assignment operator. Copy the index array - const aiFace& operator = ( const aiFace& o) + aiFace& operator = ( const aiFace& o) { if (&o == this) return *this; delete[] mIndices; mNumIndices = o.mNumIndices; - mIndices = new unsigned int[mNumIndices]; - ::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int)); + if (mNumIndices) { + mIndices = new unsigned int[mNumIndices]; + ::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int)); + } + else { + mIndices = NULL; + } return *this; } @@ -243,17 +249,17 @@ struct aiBone //! Default constructor aiBone() + : mNumWeights( 0 ) + , mWeights( NULL ) { - mNumWeights = 0; mWeights = NULL; } //! Copy constructor aiBone(const aiBone& other) + : mName( other.mName ) + , mNumWeights( other.mNumWeights ) + , mOffsetMatrix( other.mOffsetMatrix ) { - mNumWeights = other.mNumWeights; - mOffsetMatrix = other.mOffsetMatrix; - mName = other.mName; - if (other.mWeights && other.mNumWeights) { mWeights = new aiVertexWeight[mNumWeights]; @@ -314,7 +320,7 @@ enum aiPrimitiveType * compiler to map this enum to a 32 Bit integer. */ #ifndef SWIG - _aiPrimitiveType_Force32Bit = 0x9fffffff + _aiPrimitiveType_Force32Bit = INT_MAX #endif }; //! enum aiPrimitiveType @@ -373,10 +379,11 @@ struct aiAnimMesh #ifdef __cplusplus aiAnimMesh() - : mVertices() - , mNormals() - , mTangents() - , mBitangents() + : mVertices( NULL ) + , mNormals( NULL ) + , mTangents( NULL ) + , mBitangents( NULL ) + , mNumVertices( 0 ) { // fixme consider moving this to the ctor initializer list as well for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){ @@ -604,29 +611,28 @@ struct aiMesh //! Default constructor. Initializes all members to 0 aiMesh() + : mPrimitiveTypes( 0 ) + , mNumVertices( 0 ) + , mNumFaces( 0 ) + , mVertices( NULL ) + , mNormals( NULL ) + , mTangents( NULL ) + , mBitangents( NULL ) + , mFaces( NULL ) + , mNumBones( 0 ) + , mBones( NULL ) + , mMaterialIndex( 0 ) + , mNumAnimMeshes( 0 ) + , mAnimMeshes( NULL ) { - mNumVertices = 0; - mNumFaces = 0; - - mNumAnimMeshes = 0; - - mPrimitiveTypes = 0; - mVertices = NULL; mFaces = NULL; - mNormals = NULL; mTangents = NULL; - mBitangents = NULL; - mAnimMeshes = NULL; - for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { mNumUVComponents[a] = 0; mTextureCoords[a] = NULL; } + for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) mColors[a] = NULL; - mNumBones = 0; mBones = NULL; - mMaterialIndex = 0; - mNumAnimMeshes = 0; - mAnimMeshes = NULL; } //! Deletes all storage allocated for the mesh diff --git a/src/3rdparty/assimp/include/assimp/metadata.h b/src/3rdparty/assimp/include/assimp/metadata.h new file mode 100644 index 000000000..8c8880e81 --- /dev/null +++ b/src/3rdparty/assimp/include/assimp/metadata.h @@ -0,0 +1,247 @@ +/* +--------------------------------------------------------------------------- +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 metadata.h + * @brief Defines the data structures for holding node meta information. + */ +#ifndef __AI_METADATA_H_INC__ +#define __AI_METADATA_H_INC__ + +#include <assert.h> + +#if defined(_MSC_VER) && (_MSC_VER <= 1500) +#include "pstdint.h" +#else +#include <stdint.h> +#endif + + + +// ------------------------------------------------------------------------------- +/** + * Enum used to distinguish data types + */ + // ------------------------------------------------------------------------------- +typedef enum aiMetadataType +{ + AI_BOOL = 0, + AI_INT = 1, + AI_UINT64 = 2, + AI_FLOAT = 3, + AI_AISTRING = 4, + AI_AIVECTOR3D = 5, + +#ifndef SWIG + FORCE_32BIT = INT_MAX +#endif +} aiMetadataType; + + + +// ------------------------------------------------------------------------------- +/** + * Metadata entry + * + * The type field uniquely identifies the underlying type of the data field + */ + // ------------------------------------------------------------------------------- +struct aiMetadataEntry +{ + aiMetadataType mType; + void* mData; +}; + + + +#ifdef __cplusplus + +#include <string> + + + +// ------------------------------------------------------------------------------- +/** + * Helper functions to get the aiType enum entry for a type + */ + // ------------------------------------------------------------------------------- +inline aiMetadataType GetAiType( bool ) { return AI_BOOL; } +inline aiMetadataType GetAiType( int ) { return AI_INT; } +inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; } +inline aiMetadataType GetAiType( float ) { return AI_FLOAT; } +inline aiMetadataType GetAiType( aiString ) { return AI_AISTRING; } +inline aiMetadataType GetAiType( aiVector3D ) { return AI_AIVECTOR3D; } + + + +#endif + + + +// ------------------------------------------------------------------------------- +/** + * Container for holding metadata. + * + * Metadata is a key-value store using string keys and values. + */ + // ------------------------------------------------------------------------------- +struct aiMetadata +{ + /** Length of the mKeys and mValues arrays, respectively */ + unsigned int mNumProperties; + + /** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */ + C_STRUCT aiString* mKeys; + + /** Arrays of values, may not be NULL. Entries in this array may be NULL if the + * corresponding property key has no assigned value. */ + C_STRUCT aiMetadataEntry* mValues; + +#ifdef __cplusplus + + /** Constructor */ + aiMetadata() + // set all members to zero by default + : mNumProperties(0) + , mKeys(NULL) + , mValues(NULL) + {} + + + /** Destructor */ + ~aiMetadata() + { + delete[] mKeys; + mKeys = NULL; + if (mValues) + { + // Delete each metadata entry + for (unsigned i=0; i<mNumProperties; ++i) + { + void* data = mValues[i].mData; + switch (mValues[i].mType) + { + case AI_BOOL: + delete static_cast<bool*>(data); + break; + case AI_INT: + delete static_cast<int*>(data); + break; + case AI_UINT64: + delete static_cast<uint64_t*>(data); + break; + case AI_FLOAT: + delete static_cast<float*>(data); + break; + case AI_AISTRING: + delete static_cast<aiString*>(data); + break; + case AI_AIVECTOR3D: + delete static_cast<aiVector3D*>(data); + break; + default: + assert(false); + break; + } + } + + // Delete the metadata array + delete [] mValues; + mValues = NULL; + } + } + + + + template<typename T> + inline void Set( unsigned index, const std::string& key, const T& value ) + { + // In range assertion + assert(index < mNumProperties); + + // Set metadata key + mKeys[index] = key; + + // Set metadata type + mValues[index].mType = GetAiType(value); + // Copy the given value to the dynamic storage + mValues[index].mData = new T(value); + } + + template<typename T> + inline bool Get( unsigned index, T& value ) + { + // In range assertion + assert(index < mNumProperties); + + // Return false if the output data type does + // not match the found value's data type + if ( GetAiType( value ) != mValues[ index ].mType ) { + return false; + } + + // Otherwise, output the found value and + // return true + value = *static_cast<T*>(mValues[index].mData); + return true; + } + + template<typename T> + inline bool Get( const aiString& key, T& value ) + { + // Search for the given key + for (unsigned i=0; i<mNumProperties; ++i) + if (mKeys[i]==key) + return Get(i, value); + return false; + } + + template<typename T> + inline bool Get( const std::string& key, T& value ) { + return Get(aiString(key), value); + } + +#endif // __cplusplus + +}; + +#endif // __AI_METADATA_H_INC__ + + diff --git a/src/3rdparty/assimp/include/assimp/postprocess.h b/src/3rdparty/assimp/include/assimp/postprocess.h index 26060a70f..0eb9abea9 100644 --- a/src/3rdparty/assimp/include/assimp/postprocess.h +++ b/src/3rdparty/assimp/include/assimp/postprocess.h @@ -54,7 +54,10 @@ extern "C" { /** @enum aiPostProcessSteps * @brief Defines the flags for all possible post processing steps. * - * @see Importer::ReadFile + * @note Some steps are influenced by properties set on the Assimp::Importer itself + * + * @see Assimp::Importer::ReadFile() + * @see Assimp::Importer::SetPropertyInteger() * @see aiImportFile * @see aiImportFileEx */ @@ -67,7 +70,7 @@ enum aiPostProcessSteps * * Does nothing if a mesh does not have normals. You might want this post * processing step to be executed if you plan to use tangent space calculations - * such as normal mapping applied to the meshes. There's a config setting, + * such as normal mapping applied to the meshes. There's an importer property, * <tt>#AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE</tt>, which allows you to specify * a maximum smoothing angle for the algorithm. However, usually you'll * want to leave it at the default value. @@ -114,7 +117,7 @@ enum aiPostProcessSteps * solution: * <ul> * <li>Specify both #aiProcess_Triangulate and #aiProcess_SortByPType </li> - * </li>Ignore all point and line meshes when you process assimp's output</li> + * <li>Ignore all point and line meshes when you process assimp's output</li> * </ul> */ aiProcess_Triangulate = 0x8, @@ -124,7 +127,7 @@ enum aiPostProcessSteps * light sources, cameras, textures, vertex components). * * The components to be removed are specified in a separate - * configuration option, <tt>#AI_CONFIG_PP_RVC_FLAGS</tt>. This is quite useful + * importer property, <tt>#AI_CONFIG_PP_RVC_FLAGS</tt>. This is quite useful * if you don't need all parts of the output structure. Vertex colors * are rarely used today for example... Calling this step to remove unneeded * data from the pipeline as early as possible results in increased @@ -167,7 +170,7 @@ enum aiPostProcessSteps * they're usually already there. * * This flag may not be specified together with - * #aiProcess_GenNormals. There's a configuration option, + * #aiProcess_GenNormals. There's a importer property, * <tt>#AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE</tt> which allows you to specify * an angle maximum for the normal smoothing algorithm. Normals exceeding * this limit are not smoothed, resulting in a 'hard' seam between two faces. @@ -187,7 +190,7 @@ enum aiPostProcessSteps * * The split limits can (and should!) be set through the * <tt>#AI_CONFIG_PP_SLM_VERTEX_LIMIT</tt> and <tt>#AI_CONFIG_PP_SLM_TRIANGLE_LIMIT</tt> - * settings. The default values are <tt>#AI_SLM_DEFAULT_MAX_VERTICES</tt> and + * importer properties. The default values are <tt>#AI_SLM_DEFAULT_MAX_VERTICES</tt> and * <tt>#AI_SLM_DEFAULT_MAX_TRIANGLES</tt>. * * Note that splitting is generally a time-consuming task, but only if there's @@ -224,8 +227,8 @@ enum aiPostProcessSteps * important vertex weights are removed and the remaining vertex weights are * renormalized so that the weights still sum up to 1. * The default bone weight limit is 4 (defined as <tt>#AI_LMW_MAX_WEIGHTS</tt> in - * config.h), but you can use the <tt>#AI_CONFIG_PP_LBW_MAX_WEIGHTS</tt> setting to - * supply your own limit to the post processing step. + * config.h), but you can use the <tt>#AI_CONFIG_PP_LBW_MAX_WEIGHTS</tt> importer + * property to supply your own limit to the post processing step. * * If you intend to perform the skinning in hardware, this post processing * step might be of interest to you. @@ -270,8 +273,8 @@ enum aiPostProcessSteps * paper</a>). * * If you intend to render huge models in hardware, this step might - * be of interest to you. The <tt>#AI_CONFIG_PP_ICL_PTCACHE_SIZE</tt>config - * setting can be used to fine-tune the cache optimization. + * be of interest to you. The <tt>#AI_CONFIG_PP_ICL_PTCACHE_SIZE</tt> + * importer property can be used to fine-tune the cache optimization. */ aiProcess_ImproveCacheLocality = 0x800, @@ -292,7 +295,7 @@ enum aiPostProcessSteps * So, if you're passing additional information through the * content pipeline (probably using *magic* material names), don't * specify this flag. Alternatively take a look at the - * <tt>#AI_CONFIG_PP_RRM_EXCLUDE_LIST</tt> setting. + * <tt>#AI_CONFIG_PP_RRM_EXCLUDE_LIST</tt> importer property. */ aiProcess_RemoveRedundantMaterials = 0x1000, @@ -318,9 +321,9 @@ enum aiPostProcessSteps * returns, just one bit is set in aiMesh::mPrimitiveTypes. This is * especially useful for real-time rendering where point and line * primitives are often ignored or rendered separately. - * You can use the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> option to specify which - * primitive types you need. This can be used to easily exclude - * lines and points, which are rarely used, from the import. + * You can use the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> importer property to + * specify which primitive types you need. This can be used to easily + * exclude lines and points, which are rarely used, from the import. */ aiProcess_SortByPType = 0x8000, @@ -336,9 +339,9 @@ enum aiPostProcessSteps * <ul> * <li>Specify the #aiProcess_FindDegenerates flag. * </li> - * <li>Set the <tt>AI_CONFIG_PP_FD_REMOVE</tt> option to 1. This will - * cause the step to remove degenerate triangles from the import - * as soon as they're detected. They won't pass any further + * <li>Set the <tt>#AI_CONFIG_PP_FD_REMOVE</tt> importer property to + * 1. This will cause the step to remove degenerate triangles from the + * import as soon as they're detected. They won't pass any further * pipeline steps. * </li> * </ul> @@ -349,7 +352,7 @@ enum aiPostProcessSteps * <li>Specify the #aiProcess_SortByPType flag. This moves line and * point primitives to separate meshes. * </li> - * <li>Set the <tt>AI_CONFIG_PP_SBP_REMOVE</tt> option to + * <li>Set the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> importer property to * @code aiPrimitiveType_POINTS | aiPrimitiveType_LINES * @endcode to cause SortByPType to reject point * and line meshes from the scene. @@ -446,9 +449,9 @@ enum aiPostProcessSteps * * Node names can be lost during this step. If you use special 'tag nodes' * to pass additional information through your content pipeline, use the - * <tt>#AI_CONFIG_PP_OG_EXCLUDE_LIST</tt> setting to specify a list of node - * names you want to be kept. Nodes matching one of the names in this list won't - * be touched or modified. + * <tt>#AI_CONFIG_PP_OG_EXCLUDE_LIST</tt> importer property to specify a + * list of node names you want to be kept. Nodes matching one of the names + * in this list won't be touched or modified. * * Use this flag with caution. Most simple files will be collapsed to a * single node, so complex hierarchies are usually completely lost. This is not @@ -620,7 +623,6 @@ enum aiPostProcessSteps aiProcess_FindInstances | \ aiProcess_ValidateDataStructure | \ aiProcess_OptimizeMeshes | \ - aiProcess_Debone | \ 0 ) @@ -628,4 +630,4 @@ enum aiPostProcessSteps } // end of extern "C" #endif -#endif // AI_POSTPROCESS_H_INC
\ No newline at end of file +#endif // AI_POSTPROCESS_H_INC diff --git a/src/3rdparty/assimp/include/assimp/quaternion.h b/src/3rdparty/assimp/include/assimp/quaternion.h index 580e1410c..a1fcbea9f 100644 --- a/src/3rdparty/assimp/include/assimp/quaternion.h +++ b/src/3rdparty/assimp/include/assimp/quaternion.h @@ -56,8 +56,8 @@ class aiQuaterniont { public: aiQuaterniont() : w(), x(), y(), z() {} - aiQuaterniont(TReal w, TReal x, TReal y, TReal z) - : w(w), x(x), y(y), z(z) {} + aiQuaterniont(TReal pw, TReal px, TReal py, TReal pz) + : w(pw), x(px), y(py), z(pz) {} /** Construct from rotation matrix. Result is undefined if the matrix is not orthonormal. */ aiQuaterniont( const aiMatrix3x3t<TReal>& pRotMatrix); @@ -79,6 +79,8 @@ public: bool operator== (const aiQuaterniont& o) const; bool operator!= (const aiQuaterniont& o) const; + bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const; + public: /** Normalize the quaternion */ diff --git a/src/3rdparty/assimp/include/assimp/quaternion.inl b/src/3rdparty/assimp/include/assimp/quaternion.inl index 03f247f22..0230d2166 100644 --- a/src/3rdparty/assimp/include/assimp/quaternion.inl +++ b/src/3rdparty/assimp/include/assimp/quaternion.inl @@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef __cplusplus #include "quaternion.h" +#include <cmath> + // --------------------------------------------------------------------------- template<typename TReal> bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const @@ -62,19 +64,27 @@ bool aiQuaterniont<TReal>::operator!= (const aiQuaterniont& o) const return !(*this == o); } - +// --------------------------------------------------------------------------- +template<typename TReal> +inline bool aiQuaterniont<TReal>::Equal(const aiQuaterniont& o, TReal epsilon) const { + return + std::abs(x - o.x) <= epsilon && + std::abs(y - o.y) <= epsilon && + std::abs(z - o.z) <= epsilon && + std::abs(w - o.w) <= epsilon; +} // --------------------------------------------------------------------------- // Constructs a quaternion from a rotation matrix template<typename TReal> inline aiQuaterniont<TReal>::aiQuaterniont( const aiMatrix3x3t<TReal> &pRotMatrix) { - TReal t = 1 + pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3; + TReal t = pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3; // large enough - if( t > static_cast<TReal>(0.001)) + if( t > static_cast<TReal>(0)) { - TReal s = sqrt( t) * static_cast<TReal>(2.0); + TReal s = sqrt(1 + t) * static_cast<TReal>(2.0); x = (pRotMatrix.c2 - pRotMatrix.b3) / s; y = (pRotMatrix.a3 - pRotMatrix.c1) / s; z = (pRotMatrix.b1 - pRotMatrix.a2) / s; diff --git a/src/3rdparty/assimp/include/assimp/scene.h b/src/3rdparty/assimp/include/assimp/scene.h index 1d9592538..9196d1835 100644 --- a/src/3rdparty/assimp/include/assimp/scene.h +++ b/src/3rdparty/assimp/include/assimp/scene.h @@ -52,11 +52,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "camera.h" #include "material.h" #include "anim.h" +#include "metadata.h" #ifdef __cplusplus extern "C" { #endif + // ------------------------------------------------------------------------------- /** A node in the imported hierarchy. * @@ -71,16 +73,24 @@ struct aiNode /** The name of the node. * * The name might be empty (length of zero) but all nodes which - * need to be accessed afterwards by bones or anims are usually named. - * Multiple nodes may have the same name, but nodes which are accessed - * by bones (see #aiBone and #aiMesh::mBones) *must* be unique. + * need to be referenced by either bones or animations are named. + * Multiple nodes may have the same name, except for nodes which are referenced + * by bones (see #aiBone and #aiMesh::mBones). Their names *must* be unique. * - * Cameras and lights are assigned to a specific node name - if there - * are multiple nodes with this name, they're assigned to each of them. + * Cameras and lights reference a specific node by name - if there + * are multiple nodes with this name, they are assigned to each of them. * <br> - * There are no limitations regarding the characters contained in - * this text. You should be able to handle stuff like whitespace, tabs, - * linefeeds, quotation marks, ampersands, ... . + * There are no limitations with regard to the characters contained in + * the name string as it is usually taken directly from the source file. + * + * Implementations should be able to handle tokens such as whitespace, tabs, + * line feeds, quotation marks, ampersands etc. + * + * Sometimes assimp introduces new nodes not present in the source file + * into the hierarchy (usually out of necessity because sometimes the + * source hierarchy format is simply not compatible). Their names are + * surrounded by @verbatim <> @endverbatim e.g. + * @verbatim<DummyRootNode> @endverbatim. */ C_STRUCT aiString mName; @@ -102,24 +112,39 @@ struct aiNode /** The meshes of this node. Each entry is an index into the mesh */ unsigned int* mMeshes; + /** Metadata associated with this node or NULL if there is no metadata. + * Whether any metadata is generated depends on the source file format. See the + * @link importer_notes @endlink page for more information on every source file + * format. Importers that don't document any metadata don't write any. + */ + C_STRUCT aiMetadata* mMetaData; + #ifdef __cplusplus /** Constructor */ aiNode() - { // set all members to zero by default - mParent = NULL; - mNumChildren = 0; mChildren = NULL; - mNumMeshes = 0; mMeshes = NULL; + : mName("") + , mParent(NULL) + , mNumChildren(0) + , mChildren(NULL) + , mNumMeshes(0) + , mMeshes(NULL) + , mMetaData(NULL) + { } + /** Construction from a specific name */ aiNode(const std::string& name) - { // set all members to zero by default - mParent = NULL; - mNumChildren = 0; mChildren = NULL; - mNumMeshes = 0; mMeshes = NULL; - mName = name; + : mName(name) + , mParent(NULL) + , mNumChildren(0) + , mChildren(NULL) + , mNumMeshes(0) + , mMeshes(NULL) + , mMetaData(NULL) + { } /** Destructor */ @@ -134,8 +159,10 @@ struct aiNode } delete [] mChildren; delete [] mMeshes; + delete mMetaData; } + /** Searches for a node with a specific name, beginning at this * nodes. Normally you will call this method on the root node * of the scene. @@ -143,22 +170,45 @@ struct aiNode * @param name Name to search for * @return NULL or a valid Node if the search was successful. */ + inline const aiNode* FindNode(const aiString& name) const + { + return FindNode(name.data); + } + + inline aiNode* FindNode(const aiString& name) { return FindNode(name.data); } + /** @override */ - inline aiNode* FindNode(const char* name) + inline const aiNode* FindNode(const char* name) const + { + if (!::strcmp( mName.data,name))return this; + for (unsigned int i = 0; i < mNumChildren;++i) + { + const aiNode* const p = mChildren[i]->FindNode(name); + if (p) { + return p; + } + } + // there is definitely no sub-node with this name + return NULL; + } + + inline aiNode* FindNode(const char* name) { if (!::strcmp( mName.data,name))return this; for (unsigned int i = 0; i < mNumChildren;++i) { - aiNode* p = mChildren[i]->FindNode(name); - if (p)return p; + aiNode* const p = mChildren[i]->FindNode(name); + if (p) { + return p; + } } - // there is definitely no sub node with this name + // there is definitely no sub-node with this name return NULL; } @@ -328,10 +378,10 @@ struct aiScene #ifdef __cplusplus //! Default constructor - set everything to 0/NULL - aiScene(); + ASSIMP_API aiScene(); //! Destructor - ~aiScene(); + ASSIMP_API ~aiScene(); //! Check whether the scene contains meshes //! Unless no special scene flags are set this will always be true. diff --git a/src/3rdparty/assimp/include/assimp/types.h b/src/3rdparty/assimp/include/assimp/types.h index c593b6dfd..8b35bd386 100644 --- a/src/3rdparty/assimp/include/assimp/types.h +++ b/src/3rdparty/assimp/include/assimp/types.h @@ -50,6 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <memory.h> #include <math.h> #include <stddef.h> +#include <string.h> +#include <limits.h> // Our compile configuration #include "defs.h" @@ -63,6 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "quaternion.h" #ifdef __cplusplus +#include <cstring> #include <new> // for std::nothrow_t #include <string> // for aiString::Set(const std::string&) @@ -171,6 +174,16 @@ struct aiColor3D bool operator != (const aiColor3D& other) const {return r != other.r || g != other.g || b != other.b;} + /** Component-wise comparison */ + // TODO: add epsilon? + bool operator < (const aiColor3D& other) const { + return r < other.r || ( + r == other.r && (g < other.g || + (g == other.g && b < other.b) + ) + ); + } + /** Component-wise addition */ aiColor3D operator+(const aiColor3D& c) const { return aiColor3D(r+c.r,g+c.g,b+c.b); @@ -178,7 +191,7 @@ struct aiColor3D /** Component-wise subtraction */ aiColor3D operator-(const aiColor3D& c) const { - return aiColor3D(r+c.r,g+c.g,b+c.b); + return aiColor3D(r-c.r,g-c.g,b-c.b); } /** Component-wise multiplication */ @@ -244,7 +257,7 @@ struct aiString { data[0] = '\0'; -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG // Debug build: overwrite the string on its full length with ESC (27) memset(data+1,27,MAXLEN-1); #endif @@ -314,7 +327,7 @@ struct aiString /** Append a string to the string */ void Append (const char* app) { - const size_t len = strlen(app); + const size_t len = ::strlen(app); if (!len) { return; } @@ -331,7 +344,7 @@ struct aiString length = 0; data[0] = '\0'; -#ifdef _DEBUG +#ifdef ASSIMP_BUILD_DEBUG // Debug build: overwrite the string on its full length with ESC (27) memset(data+1,27,MAXLEN-1); #endif @@ -358,7 +371,7 @@ struct aiString /** Standard return type for some library functions. * Rarely used, and if, mostly in the C API. */ -enum aiReturn +typedef enum aiReturn { /** Indicates that a function was successful */ aiReturn_SUCCESS = 0x0, @@ -375,7 +388,7 @@ enum aiReturn * Force 32-bit size enum */ _AI_ENFORCE_ENUM_SIZE = 0x7fffffff -}; // !enum aiReturn +} aiReturn; // !enum aiReturn // just for backwards compatibility, don't use these constants anymore #define AI_SUCCESS aiReturn_SUCCESS diff --git a/src/3rdparty/assimp/include/assimp/vector2.h b/src/3rdparty/assimp/include/assimp/vector2.h index 800db4bd2..5ec98f4eb 100644 --- a/src/3rdparty/assimp/include/assimp/vector2.h +++ b/src/3rdparty/assimp/include/assimp/vector2.h @@ -44,7 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_VECTOR2D_H_INC #define AI_VECTOR2D_H_INC -#include <math.h> +#ifdef __cplusplus +# include <cmath> +#else +# include <math.h> +#endif #include "./Compiler/pushpack1.h" @@ -83,6 +87,8 @@ public: bool operator== (const aiVector2t& other) const; bool operator!= (const aiVector2t& other) const; + bool Equal(const aiVector2t& other, TReal epsilon = 1e-6) const; + aiVector2t& operator= (TReal f); const aiVector2t SymMul(const aiVector2t& o); diff --git a/src/3rdparty/assimp/include/assimp/vector2.inl b/src/3rdparty/assimp/include/assimp/vector2.inl index adee69017..eb1b986fa 100644 --- a/src/3rdparty/assimp/include/assimp/vector2.inl +++ b/src/3rdparty/assimp/include/assimp/vector2.inl @@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef __cplusplus #include "vector2.h" +#include <cmath> + // ------------------------------------------------------------------------------------------------ template <typename TReal> template <typename TOther> @@ -131,6 +133,14 @@ bool aiVector2t<TReal>::operator!= (const aiVector2t& other) const { return x != other.x || y != other.y; } +// --------------------------------------------------------------------------- +template<typename TReal> +bool aiVector2t<TReal>::Equal(const aiVector2t& other, TReal epsilon) const { + return + std::abs(x - other.x) <= epsilon && + std::abs(y - other.y) <= epsilon; +} + // ------------------------------------------------------------------------------------------------ template <typename TReal> aiVector2t<TReal>& aiVector2t<TReal>::operator= (TReal f) { diff --git a/src/3rdparty/assimp/include/assimp/vector3.h b/src/3rdparty/assimp/include/assimp/vector3.h index 9b84b7be3..c21e6cfde 100644 --- a/src/3rdparty/assimp/include/assimp/vector3.h +++ b/src/3rdparty/assimp/include/assimp/vector3.h @@ -44,8 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_VECTOR3D_H_INC #define AI_VECTOR3D_H_INC -#include <math.h> - +#ifdef __cplusplus +# include <cmath> +#else +# include <math.h> +#endif #include "./Compiler/pushpack1.h" @@ -86,6 +89,8 @@ public: bool operator== (const aiVector3t& other) const; bool operator!= (const aiVector3t& other) const; + bool Equal(const aiVector3t& other, TReal epsilon = 1e-6) const; + template <typename TOther> operator aiVector3t<TOther> () const; diff --git a/src/3rdparty/assimp/include/assimp/vector3.inl b/src/3rdparty/assimp/include/assimp/vector3.inl index 8938458d3..b8cbe8b49 100644 --- a/src/3rdparty/assimp/include/assimp/vector3.inl +++ b/src/3rdparty/assimp/include/assimp/vector3.inl @@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifdef __cplusplus #include "vector3.h" +#include <cmath> + // ------------------------------------------------------------------------------------------------ /** Transformation of a vector by a 3x3 matrix */ template <typename TReal> @@ -90,7 +92,7 @@ AI_FORCE_INLINE TReal aiVector3t<TReal>::SquareLength() const { // ------------------------------------------------------------------------------------------------ template <typename TReal> AI_FORCE_INLINE TReal aiVector3t<TReal>::Length() const { - return sqrt( SquareLength()); + return ::sqrt( SquareLength()); } // ------------------------------------------------------------------------------------------------ template <typename TReal> @@ -147,6 +149,14 @@ template <typename TReal> AI_FORCE_INLINE bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& other) const { return x != other.x || y != other.y || z != other.z; } +// --------------------------------------------------------------------------- +template<typename TReal> +AI_FORCE_INLINE bool aiVector3t<TReal>::Equal(const aiVector3t<TReal>& other, TReal epsilon) const { + return + std::abs(x - other.x) <= epsilon && + std::abs(y - other.y) <= epsilon && + std::abs(z - other.z) <= epsilon; +} // ------------------------------------------------------------------------------------------------ template <typename TReal> AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) { @@ -207,6 +217,7 @@ AI_FORCE_INLINE aiVector3t<TReal> operator - ( const aiVector3t<TReal>& v) { return aiVector3t<TReal>( -v.x, -v.y, -v.z); } +// ------------------------------------------------------------------------------------------------ #endif // __cplusplus #endif // AI_VECTOR3D_INL_INC diff --git a/src/3rdparty/assimp/include/assimp/version.h b/src/3rdparty/assimp/include/assimp/version.h index 620d63f73..db914eb83 100644 --- a/src/3rdparty/assimp/include/assimp/version.h +++ b/src/3rdparty/assimp/include/assimp/version.h @@ -74,11 +74,10 @@ ASSIMP_API unsigned int aiGetVersionMajor (void); // --------------------------------------------------------------------------- /** @brief Returns the repository revision of the Assimp runtime. * @return SVN Repository revision number of the Assimp runtime the - * application was linked/built against + * application was linked/built against. */ ASSIMP_API unsigned int aiGetVersionRevision (void); - //! Assimp was compiled as a shared object (Windows: DLL) #define ASSIMP_CFLAGS_SHARED 0x1 //! Assimp was compiled against STLport diff --git a/src/3rdparty/assimp/revision.h b/src/3rdparty/assimp/revision.h index 84b2dbc2d..cebfa4b16 100644 --- a/src/3rdparty/assimp/revision.h +++ b/src/3rdparty/assimp/revision.h @@ -1 +1,6 @@ -#define SVNRevision 1270 +#ifndef ASSIMP_REVISION_H_INC +#define ASSIMP_REVISION_H_INC + +#define GitVersion 0xA0bA3A8; + +#endif // ASSIMP_REVISION_H_INC |